skip to Main Content

When I am calling getUserById() function everything works fine and the growable string works fine but when I use the same variable inside a text widget then it shows RangeError.
The problem is occuring only when I try to use a growable list of string named as dataAsString inside the build.

Here is a screenshot of exception

Here is the Code with Error. Go to the scaffold where I have commented the line of error

import 'package:Healthwise/helpers/user.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import '../helpers/backEnd.dart';
import '../helpers/frontEnd.dart';

class ResultPage extends StatefulWidget {
  const ResultPage({Key? key}) : super(key: key);

  @override
  State<ResultPage> createState() => _ResultPageState();
}

class _ResultPageState extends State<ResultPage> {
  // String docId = '';
  String objectToString = '';
  String e = '';
  //This variable is creating the problem...
  // I have tried this by using a final instead of var, but nothing worked.
  var dataAsString = <String>[];

  @override
  void initState() {
    super.initState();
    // getUsers();
    getUserById();
  }

  getUserById() {
    final String id = itemName;
    userRef.doc(id).get().then((DocumentSnapshot doc) {
      // final x = doc.data();
      // docId= doc.id;
      objectToString = doc.data().toString();
      String temp = '';
      // print(doc.data());
      // print(doc.id);
      int i = 1;
      // int j = 0;
      bool end = false;
      //We are just parsing the object into string.
      while (objectToString[i] != '}') {
        if (objectToString[i - 1] == ' ' && objectToString[i - 2] == ':') {
          while (objectToString[i] != ',' && end != true) {
            // print(z[i]);
            temp += objectToString[i];
            if (objectToString[i + 1] != '}') {
              i++;
            } else {
              end = true;
            }
          }
          //Here I add all the strings to list...
          // This line works fine.
          dataAsString.add(temp);
          temp = '';
          // j++;
          print("The code below this line prints everything perfectly");
          print(dataAsString.length);
          print(dataAsString[0]);
        }
        i++;
      }
      // print(dataAsString[0]);
      // print(dataAsString[1]);
      // print("+++++++++++");
      // print(dataAsString[2]);
      // for (var k in dataAsString) {
      //   print(k);
      // }
      // print(dataAsString);

      // setState(() {});
    });
  }

  // getUsers() {
  //   userRef.get().then((QuerySnapshot snapshot) {
  //     snapshot.docs.forEach((DocumentSnapshot doc) {
  //       print(doc.data());
  //       print(doc.id);
  //       print(doc.exists);
  //     });
  //   });
  // }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(backgroundColor: primary_color, title: Text("Apple")),
      body: Container(
        child: Column(children: [
          ListTile(
            //The problem arises here and the app do not crash if I run the same code with just a //string in place of dataAsString[0]
            title: Text(dataAsString[0]),
          ),
          ListTile(
            title: Text(dataAsString[1]),
          ),
          ListTile(
            title: Text(dataAsString[2]),
          ),
        ]),
      ),
    );
  }
}

2

Answers


  1. You cant have data on dataAsString because you are using future(.then) on fetching data. You can do value check like

    Text( dataAsString.isNotEmpty? dataAsString[0]: "0 is empty"),
    
    Text( dataAsString.length>2? dataAsString[1]: "1 index is empty"),
    
    Text( dataAsString.length>3? dataAsString[2]: "3rd item is empty"),
    
    Login or Signup to reply.
  2. It’s cause your dataAsString ins’t ready on first Flutter rendered frame. So, you need to wait for the getUserById finish to access the dataAsString values.

    You can use a builder to check if the data is ready in a readable way.

    Builder(
      builder: (context) {
        if (dataAsString.length >= 2) {
          return Column(children: [
            ListTile(
              title: Text(dataAsString[0]),
            ),
            ListTile(
              title: Text(dataAsString[1]),
            ),
            ListTile(
              title: Text(dataAsString[2]),
            ),
          ]);
        } else {
          return const Center(
            child: CircularProgressIndicator(),
          );
        }
      },
    ),
    

    Warning: it’ll work cause you’re calling setState when you finish the async task.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search