Kshitij dhyani
Kshitij dhyani

Reputation: 611

setState method called after dispose()?

I am trying to fetch data from the server and then using the list .

I found a related question on stack overflow and tried using the mount property before the set state method but that doesn't seem to work.

I have tried to recreate the error with least possible code.

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

      class Test extends StatefulWidget {
        @override
        Map<String, dynamic> timelist;

        State<StatefulWidget> createState() {
          // TODO: implement createState
          return TestState();
        }
      }

      class TestState extends State<Test> {
        void initState() {
          http
              .get('https://workfeed-715b8.firebaseio.com/time.json')
              .then((http.Response response) {
            if (mounted) {
              setState(() {
                widget.timelist = json.decode(response.body);
                print(widget.timelist);
              });
            }
          });

          // TODO: implement initState

          super.initState();
        }

        @override
        Widget build(BuildContext context) {
          // TODO: implement build
          return widget.timelist != null
              ? Column(
                  children: <Widget>[
                    Expanded(
                      child: ListView.builder(
                          itemCount: widget.timelist.length,
                          itemBuilder: (BuildContext context, int index) {
                            print('Hello');
                            print(widget.timelist.length);
                          }),
                    ),
                  ],
                )
              : Text('LOADING');
        }
      }

Upvotes: 0

Views: 4587

Answers (2)

ZE0TRON
ZE0TRON

Reputation: 104

This error occurs when you try to setState of a disappeared or replaced widget's state.

You didn't define the mounted variable in your code yet you used it in a if statement. I don't know how but probably that condition holds when you replace the widget with another widget and it calls setState. This cause to that error because widget tries to set it's state after it has disappeared.

Upvotes: 1

Sasha.Z
Sasha.Z

Reputation: 1

I have tried your code and mounted property works fine. If you have any problem it's probably because you try to modify property in widget. If you have any property what need to be changed in time it must be in state class. Also if you have error because you call setState on unmounted state you can transform future to stream and cancel subscription on dispose. Complete example bellow.

class Test extends StatefulWidget {
  State<StatefulWidget> createState() {
    return TestState();
  }
}

class TestState extends State<Test> {
  String timelist;
  StreamSubscription subscription;

  void initState() {
    subscription = http.get('https://workfeed-715b8.firebaseio.com/time.json').asStream().listen((response) {
      setState(() {
        timelist = json.decode(response.body);
      });
    });
    super.initState();
  }

  @override
  void dispose() {
    subscription.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return timelist != null
        ? Column(
            children: <Widget>[
              Expanded(
                child: ListView.builder(
                    itemCount: timelist.length,
                    itemBuilder: (BuildContext context, int index) {
                      print('Hello');
                      print(timelist.length);
                    }),
              ),
            ],
          )
        : Text('LOADING');
  }
}

Upvotes: 0

Related Questions