Search code examples
flutterdartflutter-futurebuilder

My futurebuilder gives error for few seconds on the screen and then show's the result here is the error logs


Here is the Error log that I am having on IDE.

Restarted application in 1,172ms.
I/flutter (24036): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (24036): The following NoSuchMethodError was thrown building FutureBuilder<String>(dirty, state:
I/flutter (24036): _FutureBuilderState<String>#bf7da):
I/flutter (24036): The getter 'length' was called on null.
I/flutter (24036): Receiver: null
I/flutter (24036): Tried calling: length
I/flutter (24036):
I/flutter (24036): The relevant error-causing widget was:
[38;5;248mI/flutter (24036):   FutureBuilder<String>[39;49m
I/flutter (24036):
I/flutter (24036): When the exception was thrown, this was the stack:
[38;5;244mI/flutter (24036): #0      Object.noSuchMethod  (dart:core-patch/object_patch.dart:53:5)[39;49m
[38;5;248mI/flutter (24036): #1      _JsonDataState.build.<anonymous closure>[39;49m
[38;5;244mI/flutter (24036): #2      _FutureBuilderState.build[39;49m
[38;5;244mI/flutter (24036): #3      StatefulElement.build[39;49m
[38;5;244mI/flutter (24036): #4      ComponentElement.performRebuild[39;49m
[38;5;244mI/flutter (24036): #5      StatefulElement.performRebuild[39;49m
[38;5;244mI/flutter (24036): #6      Element.rebuild[39;49m
[38;5;244mI/flutter (24036): #7      ComponentElement._firstBuild[39;49m
[38;5;244mI/flutter (24036): #8      StatefulElement._firstBuild[39;49m
[38;5;244mI/flutter (24036): #9      ComponentElement.mount[39;49m
I/flutter (24036): ...     Normal element mounting (22 frames)
[38;5;244mI/flutter (24036): #31     Element.inflateWidget[39;49m
[38;5;244mI/flutter (24036): #32     MultiChildRenderObjectElement.mount[39;49m
I/flutter (24036): ...     Normal element mounting (193 frames)
[38;5;244mI/flutter (24036): #225    Element.inflateWidget[39;49m
[38;5;244mI/flutter (24036): #226    MultiChildRenderObjectElement.mount[39;49m
I/flutter (24036): ...     Normal element mounting (253 frames)
[38;5;244mI/flutter (24036): #479    Element.inflateWidget[39;49m
[38;5;244mI/flutter (24036): #480    Element.updateChild[39;49m
[38;5;244mI/flutter (24036): #481    RenderObjectToWidgetElement._rebuild[39;49m
[38;5;244mI/flutter (24036): #482    RenderObjectToWidgetElement.mount[39;49m
[38;5;244mI/flutter (24036): #483    RenderObjectToWidgetAdapter.attachToRenderTree.<anonymous

closure>[39;49m [38;5;244mI/flutter (24036): #484 BuildOwner.buildScope[39;49m [38;5;244mI/flutter (24036): #485 RenderObjectToWidgetAdapter.attachToRenderTree[39;49m [38;5;244mI/flutter (24036): #486 WidgetsBinding.attachRootWidget[39;49m [38;5;244mI/flutter (24036): #487 WidgetsBinding.scheduleAttachRootWidget.[39;49m I/flutter (24036): (elided 11 frames from class _RawReceivePortImpl, class _Timer, dart:async, and dart:async-patch) I/flutter (24036): I/flutter (24036): ════════════════════════════════════════════════════════════════════════════════════════════════════

[38;5;248m════════ Exception caught by widgets library ═══════════════════════════════════[39;49m
[38;5;244mThe following NoSuchMethodError was thrown building FutureBuilder<String>(dirty, state:

_FutureBuilderState#bf7da):[39;49m The getter 'length' was called on null. Receiver: null Tried calling: length

[38;5;244mThe relevant error-causing widget was[39;49m
    [38;5;248mFutureBuilder<String>[39;49m
[38;5;244mWhen the exception was thrown, this was the stack[39;49m
[38;5;244m#0      Object.noSuchMethod  (dart:core-patch/object_patch.dart:53:5)[39;49m
[38;5;248m#1      _JsonDataState.build.<anonymous closure>[39;49m
[38;5;244m#2      _FutureBuilderState.build[39;49m
[38;5;244m#3      StatefulElement.build[39;49m
[38;5;244m#4      ComponentElement.performRebuild[39;49m
[38;5;244m...[39;49m
[38;5;248m════════════════════════════════════════════════════════════════════════════════[39;49m

Here is the code that running. the app is running but having error and red screen for few seconds at starts.

`import 'dart:convert';
import 'package:flutter/material.dart';

class JsonData extends StatefulWidget {
  @override
  _JsonDataState createState() => _JsonDataState();
}

class _JsonDataState extends State<JsonData> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Page Data Visualization'),
      ),
      body: Center(
        child: FutureBuilder(
            builder: (context, snapshot) {
              var myData = json.decode(snapshot.data.toString());
              return ListView.builder(
                itemBuilder: (BuildContext context, int index) {
                  return Card(
                    child: ListTile(
                      leading: CircleAvatar(
                          child: Text(myData[index]['trade_code'][0])),
                      title: Text(myData[index]['trade_code']),
                      subtitle: Column(
                        crossAxisAlignment: CrossAxisAlignment.stretch,
                        children: <Widget>[
                          Text(
                            "\nHigh:" + myData[index]['high'],
                            style: TextStyle(fontWeight: FontWeight.bold),
                            textAlign: TextAlign.left,
                          ),
                          Text(
                            "Low:" + myData[index]['low'],
                            style: TextStyle(fontWeight: FontWeight.bold),
                            textAlign: TextAlign.left,
                          ),
                          Text(
                            "Open:" + myData[index]['open'],
                            style: TextStyle(fontWeight: FontWeight.bold),
                            textAlign: TextAlign.left,
                          ),
                          Text(
                            "Close:" + myData[index]['close'],
                            style: TextStyle(fontWeight: FontWeight.bold),
                            textAlign: TextAlign.left,
                          ),
                          Text(
                            "Volume:" + myData[index]['volume'],
                            style: TextStyle(fontWeight: FontWeight.bold),
                            textAlign: TextAlign.left,
                          ),
                          Text(
                            "\nDate:" + myData[index]['date'],
                            style: TextStyle(fontWeight: FontWeight.bold),
                            textAlign: TextAlign.center,
                          ),
                        ],
                      ),
                      isThreeLine: true,
                    ),
                    elevation: 3,
                  );
                },
                itemCount: myData.length,
              );
            },
            future: DefaultAssetBundle.of(context)
                .loadString("assets/stock_market_data.json")),
      ),
    );
  }
}
`

Solution

  • Your builder function executes a couple of times. First, with no data. Later, with data.

    However, you are assuming that it always has data, by doing this:

                  var myData = json.decode(snapshot.data.toString());
    

    here, snapshot.data is null initially. This is why you're getting an exception.

    Just follow the pattern in the docs. https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html

            if (snapshot.hasData) {
              var myData = json.decode(snapshot.data.toString());
            } else if (snapshot.hasError) {
              // show error widget
            } else {
              // show loading widget
            }
    
    

    some concrete examples from a recent talk of mine:

    https://youtu.be/p8dY_tsAbx8?t=5382

    https://youtu.be/p8dY_tsAbx8?t=5633

    Also, this usage is also not good, you are creating a future every time the build function executes:

                future: DefaultAssetBundle.of(context)
                    .loadString("assets/stock_market_data.json")),
    

    Instead you should cache that future in iniState. Explained here: https://youtu.be/p8dY_tsAbx8?t=5683