1

I am trying to lode data from an api call that retrieves a map, I am able to get the map from the api to display how I want it to, however it repeatedly calls the api meaning the list keeps on refreshing. Even though I have tried setting the listener to false, it works but I have to manually refresh the app for it to work?

Additional Info: Assigning and Retrieving Data


import 'package:http/http.dart' as http;

class Stores with ChangeNotifier {

  var s_length;

  Future<List<Store>> getStores(String storeCatName) async {
    final queryParameters = {
      "store_category_name": storeCatName,
    };
    try {
      //TODO this is the issue - must fix.
      final uri = Uri.http("url", 'url', queryParameters);
      //print(uri);
      final response = await http.get(uri);
      //print(response.statusCode);
      //print(response.body);
      if (response.statusCode == 200) {
        final List<Store> stores = storeFromJson(response.body);
        _stores = stores;
        //print(_stores);
        print("lenght: ${_stores.length}");
        Store store;
        for(store in _stores) {
          store.products = Products().products(store.storeId);
        }
        //check if this is correct
        notifyListeners();
        //return stores;

      } else {
        print("error1");
        return List<Store>();
      }
    } catch (e) {
      print(e.toString());
      return List<Store>();
    }
    //notifyListeners();
    print(_stores);
  }

  List<Store> get favoriteItems {
    //return _stores.where((storeItem) => storeItem.isFavorite).toList();
  }

  bool isNotFull(){
    if (_stores.isEmpty){
      return true;
    } else {
      return false;
    }
  }

  int get numberOfStores{
    return s_length;
  }

  List<Store> _stores = [];

  List<Store> stores (String storeCatName){

    getStores(storeCatName);
    //print("cpp; + $s_length");
    //notifyListeners();
    return _stores;
  }

}

 final storesProvider = Provider.of<Stores>(
      context, listen: false
    );

    storesProvider.getStores(categoryName);

    final providerStoreList = storesProvider.stores(category.storeCategoryName);

Additional Info: Builder for List:

child: ListView.builder(
            itemCount: providerStoreList.length,
            itemBuilder: (context, index) => ChangeNotifierProvider.value(
                  value: providerStoreList[index],
                  child: StoreItem(),
                )));

If any additional information is required just let me know. Any help would be greatly appreciated.

Thanks

2 Answers2

0

Use

listen: false;

   var ourClient = Provider.of<CartBlock>(context, listen: false);
  • When I set listen to false, it doesn't load the data the first time . Instead I have to refresh the app using ctrl + s and then it will display as intended. – Adarsh Manoj Feb 08 '21 at 05:44
  • for this u need to call the provider in your init() method then 1st time it wont be a problem for you and then it will work , do listen false. – Tasnuva Tavasum oshin Feb 08 '21 at 06:00
0

Setting the listener to false means that your widget won't build again when notifyListeners() is called.

So, that might not be the issue.

The only reason I can think of is calling the API again from the build method, which might happen if you are using a ListView builder. So, every time you might be scrolling the ListView your API would call again.

Hasip Timurtas
  • 983
  • 2
  • 11
  • 20
Nitesh
  • 438
  • 2
  • 10
  • It is being called later in a ListView builder, so how would I then rectify this? – Adarsh Manoj Feb 08 '21 at 09:15
  • You should not use your stores() function in the ListView rather use a variable , so you get the already stored value, and not call the function which in turn calls your API. Also, adding your build method snippet would help. – Nitesh Feb 08 '21 at 10:49
  • @AdarshManoj I completely agree with HasipTimurtas...you should not call the getstores method in builder, calling it at the time of initState would help... – Adarsh Srivastava Feb 11 '21 at 06:30