Home > other >  Flutter: Index out of range error, List Element Availability In Widget
Flutter: Index out of range error, List Element Availability In Widget

Time:12-05


import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

import '../data/monthly_cpi.dart';
import '../model/monthlycpi.dart';

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

  @override
  _MonthlyCPIListState createState() => _MonthlyCPIListState();
}

class _MonthlyCPIListState extends State<MonthlyCPIList> {
  List<MonthlyCPI> monthlyCPIList = [];

  void getMonthlyCPIfromApi() async {
    var url = Uri.parse('http://127.0.0.1:8000/');
    final response = await http.get(url);
    Iterable decoded_response = json.decode(response.body);
    monthlyCPIList = decoded_response.map((model) => MonthlyCPI.fromJson(model)).toList();
  }

  @override
  void initState() {
    super.initState();
    getMonthlyCPIfromApi();
    print(monthlyCPIList.elementAt(0).cpi_description);
  }

My code is above. What I'm not understanding is if I put the statement:

print(monthlyCPIList.elementAt(0).cpi_description); at the end of the getMonthlyCPIfromAPI() method, the element prints fine.

However, if I place the print statement at the end of the initState() method, I get an error:

Index out of range, no indices are valid: 0. I feel like I'm missing something fundamental about the context flutter sets around lists (i.e. local vs global etc.). Any help would be much appreciated, thank you!

CodePudding user response:

  • getMonthlyCPIfromApi() is an async function internally but for initState it's just another function call, hence initState code doesn't wait for getMonthlyCPIfromApi() to complete and then execute print(monthlyCPIList.elementAt(0).cpi_description);

  • initState itself is not an async function, if you try to add async and await on initState you will get errors, print statement would not have thrown any error if the code was something like this which is not possible since its an overridden function

         INCORRECT CODE (HYPOTHETICAL EXAMPLE)
         @override
         void initState() async {
               super.initState();
               await getMonthlyCPIfromApi();
               print(monthlyCPIList.elementAt(0).cpi_description);
         }
    
  • To make your code work what can be done is

         getMonthlyCPIfromApi().then((value) {
         print(monthlyCPIList.elementAt(0).cpi_description);});
    
  • Related