Developer
Developer

Reputation: 789

I am facing Range Error when I fetch data from JSON file

I made a function to fetch data from json file and I show that data to one page when ever my fetch function run it show an erorr for the time till Json fetch that is 3 to 4 second after that data fetch and show succesfully but that error show on screen is very awkward.

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

void main() => runApp(News1());

class News1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(

      title: "Flutter",
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List data = [];

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

  void fetchData() async {
    final response = await http.get('jsonfilelinkhere');

    if (response.statusCode == 200) {
      setState(() {
        data = json.decode(response.body);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    SystemChrome.setPreferredOrientations(
        [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
    return Scaffold(

      body: Padding(
          padding: EdgeInsets.only(left: 50 ,right: 50),
        child:ListView(
          children: <Widget>[
            Center(
              child: Text(data[3]['Head']),
            ),
            Center(
              child: Text(data[0]['Description']),
            ),
            Image.network(data[0]['ImgUrl']),

          ],
        ),
      )
    );
  }
}

Upvotes: 0

Views: 202

Answers (3)

DmDev
DmDev

Reputation: 602

hope you got your answer. In case you can make a check that while your array is equal to null show CircularProgressIndicator(), else show data. If you are unable to do so I can share the code for you.

Upvotes: 1

Gilson Cavalcanti
Gilson Cavalcanti

Reputation: 1513

your fetchData() function is asynchronous, so your app tap the back of your function saying "hi, fetchData() start to work!!" but your app goes on minding its own job.

And you gave this job for it:

              child: Text(data[3]['Head']),

so your app will hit this line of code while your data variable still is an empty list.

You have to prepare it for this situation. You can prepare the default value of the data or you can check if it's empty in the Widgets that depends on it.

Upvotes: 0

Son of Stackoverflow
Son of Stackoverflow

Reputation: 1679

You encountered that error as you displayed that data before it could actually load.

Use FutureBuilder to solve your issue.

Example code:

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

void main() => runApp(News1());

class News1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(

      title: "Flutter",
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List data = [];

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

  Future<Map<String, dynamic>> fetchData() async {
    final response = await http.get('jsonfilelinkhere');

    if (response.statusCode == 200) {
      setState(() {
        return json.decode(response.body);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    SystemChrome.setPreferredOrientations(
        [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
    return Scaffold(

      body: Padding(
          padding: EdgeInsets.only(left: 50 ,right: 50),
        child:FutureBuilder<Map<String, dynamic>>(
        future: fetchData, // async work
        builder: (context,snapshot) {
           switch (snapshot.connectionState) {
             case ConnectionState.waiting: return new Center(child: Text('Loading....'));
             default:
               if (snapshot.hasError)
                  return Text("Error!");
               else{
              data = snapshot.data;
              return ListView(
          children: <Widget>[
            Center(
              child: Text(data[3]['Head']),
            ),
            Center(
              child: Text(data[0]['Description']),
            ),
            Image.network(data[0]['ImgUrl']),

          ],
        )}
            }
         },
        ),
      )
    );
  }
}

Upvotes: 0

Related Questions