jack Carrol
jack Carrol

Reputation: 1

Strange behavior of notifyListener

I have a list which is fetched from the server but when we get outside of the fetching method the list is initialized to default. I have noticed that the problem is with the notifyListeners() as here: Does notifyListeners() sometimes complete asynchronously?

Interestingly, inside the fetching method the the list is ok.

class Products with ChangeNotifier {

  List<Product> _loadedProducts = [];

  Future<void> fetchAndSetProducts() async {
    try {
      var response =
          await http.get(StoreServer.serverAddress + '/products.json');

      final extractedData = json.decode(response.body) as Map<String, dynamic>;
      List<Product> extractedList = [];
      extractedData.forEach((key, value) {
        _loadedProducts.add(Product(
            id: key,
            imageUrl: value['imageUrl'],
            title: value['title'],
            price: value['price'],
            description: value['description'],
            isFavorite: value['isFavorite']));
      });
      _loadedProducts = extractedList;
      notifyListeners();
      await Future.delayed(Duration(seconds: 1));
    } catch (error) {
      throw error;
    }
  }

 @override
  void didChangeDependencies() {
    if (!isInit) {
      setState(() {
        isLoading = true;
      });
      test = Provider.of<Products>(context);
      test.fetchAndSetProducts().then((_) {
        print("fetched");
        setState(() {
          isLoading = false;
          isInit = true;
        });
      });
    }
    super.didChangeDependencies();
  }

Upvotes: 0

Views: 64

Answers (1)

Lucas Rueda
Lucas Rueda

Reputation: 176

You have a logic error. Check my comments..!

class Products with ChangeNotifier {

  List<Product> _loadedProducts = [];

  Future<void> fetchAndSetProducts() async {
    try {
      var response =
          await http.get(StoreServer.serverAddress + '/products.json');

      final extractedData = json.decode(response.body) as Map<String, dynamic>;
      List<Product> extractedList = []; // it is an empty list
      extractedData.forEach((key, value) {
        _loadedProducts.add(Product(    // you add elements to _loadedProducts 
            id: key,
            imageUrl: value['imageUrl'],
            title: value['title'],
            price: value['price'],
            description: value['description'],
            isFavorite: value['isFavorite']));
      });
      _loadedProducts = extractedList; // you reassign _loadedProducts to the empty list "extractedList"
      notifyListeners();
      await Future.delayed(Duration(seconds: 1));
    } catch (error) {
      throw error;
    }
  }

Am I right? I think you have that error!

Upvotes: 1

Related Questions