'RangeError (index): Invalid value: Valid value range is empty: 0

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. Can you please tell me 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),
          ],
        ),
      ),
    );
  }


Solution 1:[1]

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();
            });

Solution 2:[2]

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] : '') );

Solution 3:[3]

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.

Solution 4:[4]

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. 
}

Solution 5:[5]

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.

Solution 6:[6]

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!

Solution 7:[7]

I assume you getting data from fetch ApI method, If you are getting data in fetchApI metod. then you should follow this

fetchApI and is asynchronous method so it takes time to get data from json and in the begging fetchApI is empty, so it gives error of range. you can make fetchApI method asynchronous using await and async* and while calling that method use .then method and then access values.

fetchApI().then((){ // access fetchApI over here });

Solution 8:[8]

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

Solution 9:[9]

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}"),

Solution 10:[10]

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"]}"),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
          ],
        ),
      ),

Solution 11:[11]

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