68

I am trying to fetch a list from API that is two methods fetchImages and fetchCategories. The first time it is showing a red screen error and then after 2 seconds automatically it is loading the list.

What's the issue with my code and how to avoid showing that red screen error in my app?

Widget build(context) {
    try{
      if (isFirst == true) {
        fetchImage();
        fetchCategories(context);
        isFirst = false;
      }
    }catch(Exception){

    }

    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.black,
        appBar: AppBar(
          title: Text('Lets see images!'),
        ),
        body: new Column(
          children: <Widget>[
            new Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new InkResponse(
                    child: new Column(
                      children: <Widget>[
                        Padding(
                          padding: EdgeInsets.all(10.0),
                          child: new Image.asset(
                            catimages[0],
                            width: 60.0,
                            height: 60.0,
                          ),
                        ),
                        new Text(
                          categoriesText[0],
                          style: TextStyle(color: Colors.white),
                        ),
                      ],
                    ),
                    onTap: () {
                      debugPrint("on tv clikced");
                      widget.fetchApI.fetchSubCategories(context, 6);
                    }),
                new InkResponse(
                  child: new Column(
                    children: <Widget>[
                      Padding(
                        padding: EdgeInsets.all(10.0),
                        child: new Image.asset(
                          catimages[1],
                          width: 60.0,
                          height: 60.0,
                        ),
                      ),
                      new Text(
                        categoriesText[1],
                        style: TextStyle(color: Colors.white),
                      ),
                    ],
                  ),
                  onTap: () {
                    debugPrint("on moview clicked");
                    widget. fetchApI.fetchSubCategories(context, 7);
                  },
                ),
                new InkResponse(
                  child: new Column(
                    children: <Widget>[
                      Padding(
                        padding: EdgeInsets.all(10.0),
                        child: new Image.asset(
                          catimages[2],
                          width: 60.0,
                          height: 60.0,
                        ),
                      ),
                      new Text(
                       categoriesText[2],
                        style: TextStyle(color: Colors.white),
                      ),
                    ],
                  ),
                  onTap: () {
                    debugPrint("on news clicked");
                    widget.fetchApI.fetchSubCategories(context, 10);
                  },
                ),
                new InkResponse(
                  child: new Column(
                    children: <Widget>[
                      Padding(
                        padding: EdgeInsets.all(10.0),
                        child: new Image.asset(catimages[3],
                            width: 60.0, height: 60.0),
                      ),
                      new Text(
                        categoriesText[3],
                        style: TextStyle(color: Colors.white),
                      ),
                    ],
                  ),
                  onTap: () {
                    debugPrint('on shows clicked');
                    widget.fetchApI.fetchSubCategories(context, 8);
                  },
                ),
                new InkResponse(
                  child: new Column(
                    children: <Widget>[
                      Padding(
                        padding: EdgeInsets.all(10.0),
                        child: new Image.asset('assets/live_icon.png',
                            width: 60.0, height: 60.0),
                      ),
                      new Text(
                        'Live',
                        style: TextStyle(color: Colors.white),
                      ),
                    ],
                  ),
                  onTap: () {
                    debugPrint('on live clicked');
                  },
                ),
              ],
            ),
            ImageList(images,widget.fetchApI),
          ],
        ),
      ),
    );
  }
8
  • 6
    "first time it is showing redscreen error" - nobody knows what "redscreen error " really is - if you have any exceptions post the full stacktrace Commented Mar 4, 2019 at 7:02
  • RangeError (index): Invalid value: Valid value range is empty: 0, This is the exception showing on mobile Commented Mar 4, 2019 at 7:20
  • it also says where it happened: source file name, line number and position in that line, so what are those values? Commented Mar 4, 2019 at 7:22
  • 3
    sounds like it takes 2 seconds to load the data, but you're trying to display it immediately - with asynchronous processes you always need to wait until it's finished Commented Mar 4, 2019 at 7:27
  • @pskink, when I am trying to display the text categoriesText[0] there is showing error Commented Mar 4, 2019 at 7:29

17 Answers 17

57

Make sure specifying the length of the list of data. For example, if you're using ListView.builder give proper value to the attribute itemCount.

ListView.builder(
            itemCount: snapshot.data.length,
            itemBuilder: (ctx, index) {
              return WidgetItem();
            });
Sign up to request clarification or add additional context in comments.

3 Comments

as i tried this, it shows the following error, The following NoSuchMethodError was thrown building StreamBuilder<List<OrderModel>>(dirty, state: _StreamBuilderBaseState<List<OrderModel>, AsyncSnapshot<List<OrderModel>>>#155e0): The getter 'length' was called on null. Receiver: null Tried calling: length
This simple solution was all it took for me to solve it. But i am curious why the Builder can't resolve the size itself. Perhaps it could be because the data to be listed isn't always present at some base node but deeply nested in further nodes.
People should not vote up this answer since the OP isn't using builder
26

The problem can be that you are trying to access a variable/array that is not ready yet (maybe because the future/api call is not finished)

A quick workaround could be to check the length of the array or check for null, example:

Text( (myArray?.length > 0 ? myArray[0] : '') );

Comments

16

There are quick-and-dirty answer, and proper answer

Quick-and-dirty

Use list?.elementAt(<index>) ?? "" for safe access to element of a list

Widget build(context) {
    try{
      if (isFirst == true) {
        fetchImage();
        fetchCategories(context);
        isFirst = false;
      }
    }catch(Exception){

    }

    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.black,
        appBar: AppBar(
          title: Text('Lets see images!'),
        ),
        body: new Column(
          children: <Widget>[
            new Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new InkResponse(
                    child: new Column(
                      children: <Widget>[
                        Padding(
                          padding: EdgeInsets.all(10.0),
                          child: new Image.asset(
                            catimages?.elementAt(0) ?? "",
                            width: 60.0,
                            height: 60.0,
                          ),
                        ),
                        new Text(
                          categoriesText?.elementAt(0) ?? "",
                          style: TextStyle(color: Colors.white),
                        ),
                      ],
                    ),
                    onTap: () {
                      debugPrint("on tv clikced");
                      widget.fetchApI.fetchSubCategories(context, 6);
                    }),
                new InkResponse(
                  child: new Column(
                    children: <Widget>[
                      Padding(
                        padding: EdgeInsets.all(10.0),
                        child: new Image.asset(
                          catimages?.elementAt(1) ?? "",
                          width: 60.0,
                          height: 60.0,
                        ),
                      ),
                      new Text(
                        categoriesText?.elementAt(1) ?? "",
                        style: TextStyle(color: Colors.white),
                      ),
                    ],
                  ),
                  onTap: () {
                    debugPrint("on moview clicked");
                    widget. fetchApI.fetchSubCategories(context, 7);
                  },
                ),
                new InkResponse(
                  child: new Column(
                    children: <Widget>[
                      Padding(
                        padding: EdgeInsets.all(10.0),
                        child: new Image.asset(
                          catimages?.elementAt(2) ?? "",
                          width: 60.0,
                          height: 60.0,
                        ),
                      ),
                      new Text(
                       categoriesText?.elementAt(2) ?? "",
                        style: TextStyle(color: Colors.white),
                      ),
                    ],
                  ),
                  onTap: () {
                    debugPrint("on news clicked");
                    widget.fetchApI.fetchSubCategories(context, 10);
                  },
                ),
                new InkResponse(
                  child: new Column(
                    children: <Widget>[
                      Padding(
                        padding: EdgeInsets.all(10.0),
                        child: new Image.asset(catimages?.elementAt(3) ?? "",
                            width: 60.0, height: 60.0),
                      ),
                      new Text(
                        categoriesText?.elementAt(3) ?? "",
                        style: TextStyle(color: Colors.white),
                      ),
                    ],
                  ),
                  onTap: () {
                    debugPrint('on shows clicked');
                    widget.fetchApI.fetchSubCategories(context, 8);
                  },
                ),
                new InkResponse(
                  child: new Column(
                    children: <Widget>[
                      Padding(
                        padding: EdgeInsets.all(10.0),
                        child: new Image.asset('assets/live_icon.png',
                            width: 60.0, height: 60.0),
                      ),
                      new Text(
                        'Live',
                        style: TextStyle(color: Colors.white),
                      ),
                    ],
                  ),
                  onTap: () {
                    debugPrint('on live clicked');
                  },
                ),
              ],
            ),
            ImageList(images,widget.fetchApI),
          ],
        ),
      ),
    );
  }
}

Proper answer

Frankly, if I were to review this code, even if it works seamlessly, I would reject this change, because of the structure/pattern this code is using is quite bad.

Please use FutureBuilder, StreamBuilder or ValueListenableBuilder instead, but you need to provide more code (especially fetchImage and fetchCategories) for us to help.

1 Comment

list?.elementAt(<index>) ?? "" Its not working, if index is not found it keeps throwing a range error. See this comment: stackoverflow.com/a/67972681/10126563
15

Null safe

Reason for error:

This error occurs on retrieving the value for an index that doesn't exist in the List. For example:

List<int> list = [];
list[0]; // <-- Error since there's no element at index 0 in the list. 

Solution:

Check if the the List is not null and has the element at index:

var myList = nullableList;
var index = 0;
if (myList != null && myList.length > index) {
  myList[index]; // You can safely access the element here. 
}

3 Comments

I agree it has something to do with the index variable of a list. In my case I used List.generate() to create an empty list (length = 0), and then the error arose. It seems that the list cannot have a length of zero, meaning List.generate() can't be used to create an empty list.
@mathems32 You can create an empty list using List.generate(0, (i) => i).
Thank you for your response. I wrote something like that and that's when the error came. I ended up working around it. Have you ran that code, and how did Flutter respond if yes please?
4

You must specify the length of the list of data. For example, if you're using ListView along with builder function then you must provide its item length count as itemCount.

ListView.builder(
   shrinkWrap: true,
   itemCount: snapshot.data.length,
   itemBuilder: (context, index) {
      return //your widget
 });

Comments

2

I got same issue when tried to access a array which was empty. This was as part of null safety.

my earlier code was

TextBox(response.customerDetails!.address![0].city),

which caused me error so I changed the code to

Text(
     (response.cutomerDetails.address.isNotEmpty) 
        ? response.customerDetails!.address![0].city 
        : "N/A",
),

add a check when accessing arrays. This helped me remove the error.

Comments

1

You are not getting the data. The data folder from or data source is missing. The same happened for me. Later, I created the json file for data and pointed to that location. And it got fixed simply!

Comments

1

It happens when you are going to fetch some data but it is not available on that index/position

So, you have to check the index/position value where it is null or not

In my case Listview -> itemcount was perfect but showing this error And then solved it by following checking code

Text("${(widget.topSellItem.subjects.isEmpty) ? "" : widget.topSellItem!.subjects[0].subject.name}"),

Comments

1

I have solved this issue in flutter null safety version by following way.

Reason : It happened when value is not available for that index.

You can check itemCount item value is available or not at builder,

Solution with Null Safety would be like :

ListView.builder(
    itemCount: snapshot.data!.items.length,    //OR snapshot.data!.length
    itemBuilder: (context, index) {
          return (index > 0) ? YourWidget() : Container();
 });

Comments

1

Had same problem when accessing empty arrays, and fix it this ways : data.allData[index].reviews!.isEmpty ? 0 : data.allData[index].reviews![0].rating

when there's data in it, it will access first index.

Comments

1

This error comes because of these reasons.

  1. Not using a builder in a screen.
  2. While using a builder we have to provide a condition that checking the list was empty or not. If the list is empty we have to show a circular progress indicator and the list is not empty we can show the list.

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
1

I faced the same issue, I solved by using a boolean variable of loading state:

First: declare bool _loading = false; Second: before calling fetch API setState({ _loading = true;}); Third: set timer of two second Forth: After time setState({ _loading = false;}); Finally: on the body of UI ..... child: _loading? CircularProgressIndicator() : yourWidget

Comments

0

If you are fetching data from the API consider using FutureBuilder.

Comments

0

In case the other methods don't work, check if your database contains any conflicting data entries. If so, fix them.

Comments

0

First, declare the array of objects.

late Map<String, dynamic> product={};

the HTTP answer is:

{
  "id": "1",
  "codigo": "mw9wcsABvk",
  "nombre": "Router TPLink Gaming 5G",
  "portada": [
    {
      "url": "/php/assets/producto/mw9wcsABvk/2729233.png",
      "name": "2729233.png"
    }
  ]
}

In Widget build

      body: Center(
        child: Column(
          children: [
            if(producto.isNotEmpty)
              Expanded(
                child: Column(
                  children: [
                    ConstrainedBox(
                      constraints: BoxConstraints.tight(Size(double.infinity, 256)),
                      child: Stack(
                        alignment: AlignmentDirectional.center,
                        children: [
                          Positioned(
                            child: Image.network("${host}${producto["portada"][0]["url"]}"),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
          ],
        ),
      ),

Comments

0

If the error RangeError (index): Invalid value: Valid value range is empty arises on such structures

Text(rapportDataList[index].rapport)

it can be fixed with the following

Text(rapportDataList.isNotEmpty ? rapportDataList[index].rapport : '')

Comments

-3

To me, going to the project directory and running the command flutter clean fixed the error

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.