Q:

Flutter - "Range error (length)" when trying to parse local json data

I have a JSON file that has a text and each sentence is in a separate JSON object, the user shoud be able to navigate between sentenes with next() and previous() but when the app loads I get this error:

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

until I press any other button on the screen that's when the text loads and get displayed.
The card itself is a statefulWidget and here's my code:
class _BottomCardsState extends State<BottomCards>{

  bool isLoadingEnded = false;

  Future<Null> getAllData() async{
    await DefaultAssetBundle.of(context).loadString('assets/json/data.json').then((response){
      isLoadingEnded = true;
      var decodedData = json.decode(response);
        for(Map d in decodedData){
          dataList.add(Data.fromJson(d));
        }      
    });
  }

  @override
  void initState() {
    super.initState();
    getAllData();
  }

  int dataIndex = 0;

  @override
  Widget build(BuildContext context) {
    int myNbr = dataList[dataIndex].id;
    return Container(
      child: Material(
        color: Colors.transparent,
        child: Card(
          margin: EdgeInsets.symmetric(horizontal: 10.0),
          elevation: 6.0,
          child: Container(
            alignment: Alignment.topCenter,
            padding: EdgeInsets.symmetric(horizontal: 12.0,),
            child: Column(
              children: <Widget>[
                Row(
                  children: <Widget>[
                    IconButton(                  
                      splashColor: gradientStart,
                      icon: Icon(Icons.keyboard_arrow_left,),
                      onPressed: () {_previous();},
                    ),
                    IconButton(
                      splashColor: gradientStart,
                      icon: Icon(Icons.keyboard_arrow_right,),
                      onPressed: () {_next();},
                    ),
                  ],
                ),
                SizedBox(height: 4.0,),
                isLoadingEnded == true ? Container(
                  child: Column(
                    children: <Widget>[
                      Row(
                        mainAxisAlignment: MainAxisAlignment.start,
                        mainAxisSize: MainAxisSize.max,
                        children: <Widget>[
                          Expanded(                  
                            child: InkWell(
                              splashColor: Colors.lightBlue[100],
                              onTap: (){},
                              //the paragraph gets displayed here
                              child: Text(dataList[dataIndex].paragraph,
                            ),
                          ),
                        ],
                      ),
                      SizedBox(height: 8.0,),
                      Row(
                        mainAxisAlignment: MainAxisAlignment.end,
                        mainAxisSize: MainAxisSize.max,
                        children: <Widget>[
                          Chip(
                            backgroundColor: secondaryDark,
                            label: Text('Number: $myNbr',
                            style: TextStyle(color: Colors.white, fontSize: 10.0, fontWeight: FontWeight.w500),),
                          ),
                        ],
                      ),
                    ],
                  ),
                ): Center(child: loadingIndicator(),),
                SizedBox(height: 6.0),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

`
My JSON format:
{
    "id": 1,
    "paragraph": "lorem ipsum"
},
...

A:

You need to wait until data is filled up.
change your getAllData method. Like,
Future<List<Data>> getAllData() async{
    var response = await DefaultAssetBundle.of(context).loadString('assets/json/data.json')
    var decodedData = json.decode(response);
    for(Map d in decodedData){
        dataList.add(Data.fromJson(d));
    }  
    return dataList;
}

and now wait on build method. Like,
@override
  Widget build(BuildContext context) {
   return FutureBuilder<List<Data>>(
        future: getAllData(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
             print("Here you can get data "+snapshot.data.toString());
            //you can put your ui here
          } else {
            print("Waiting mode");
            return Container(
              color: Colors.blue,
            );
          }
        },
      )
}

