Home > Blockchain >  Provider: How can I `notifyListener()` within a `StreamBuilder()`? It causes the error `setState() o
Provider: How can I `notifyListener()` within a `StreamBuilder()`? It causes the error `setState() o

Time:06-28

I have a Provider model such as provider_model.dart:

import 'package:flutter/material.dart';

class ProviderModel extends ChangeNotifier {
  final List<String> _myList = [];

  List<String> get myList => [..._myList];

  void addItem(String item) {
    _myList.add(item);
    notifyListeners();
  }
}

Now, Flutter documentation enter image description here Now, when I click on the send button, it calls _sendMessage() (code above). And then since the StreamBuilder() hasData it runs this line (code above):

provider.addItem('I was added');

However, this is where my error appears, I am getting the following error:

The following assertion was thrown while dispatching notifications for ProviderModel:
setState() or markNeedsBuild() called during build.

CodePudding user response:

You can take help from addPostFrameCallback, but the cost is it will keep rebuilding on every frame, to control this behavior you can use a bool on state class.

  bool isDone = false;

  void addItemH() {
    if (!isDone) {
      WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
        Provider.of<ProviderModel>(context, listen: false)
            .addItem('I was added');
        isDone = true;
      });
    }
  }

And builder

 builder: (context, snapshot) {
                if (snapshot.hasData) {
                  addItemH();
                  return Text("Item added");

And to control the next insertaion.

  void _sendMessage() {
    if (_controller.text.isNotEmpty) {
      isDone = false;
      _channel.sink.add(_controller.text);
      print('done');
    }
  }
}

If you just want to add data only single time, it is better to do inside inside initState.

  • Related