0

I'm reading json List from device memory and want to perform some operations on it's components.

When I load that list I start loop where I check each item of that list. While in loop I add each item to new List to have updated List after loop ends so I could save it on device memory. If some conditions are true then I use future async http call to get updated data then theoretically I update that item of the List while staying inside loop. And thus after loop ends I must have updated Json List ready to be saved on device memory. Problem is that While I http call inside loop, the answer delays, loop ends and new Json List is being constructed and saved on memory without the component that was supposed to be updated. Is there any way to force wait the whole loop or something else ?

Here is the code

 Future<void> readStoredData() async {
    try {
final prefs = await SharedPreferences.getInstance();
   
      _rawJsonListE = prefs.getStringList('storedData');
   
        List<String> rawJsonListNEW = [];
        bool _isNeedUpdate = false;
        _rawJsonListE!.forEach((item) async {         
          if (someCondition with item Data) {
            _isNeedUpdate = true;
            await makeHttpCallFutureAwaitFunction(item).then((_) {
              rawJsonListNEW.add(updatedItem);
            });
          } else {
            rawJsonListNEW.add(item);
          }
        });
        if (_isNeedUpdate) prefs.setStringList('storedData', rawJsonListNEW);
      }
    
      notifyListeners();
} catch (error) {
  print('Error : ${error}');
  throw error;
}
David
  • 4,332
  • 13
  • 54
  • 93
  • 2
    do not use `_rawJsonListE!.forEach`, instead use "normal' `for(final item in _rawJsonListE!)` – pskink Jul 26 '22 at 08:47
  • gave it a try, no luck. works same in my case – David Jul 26 '22 at 08:48
  • 1
    see https://stackoverflow.com/a/63719805/2252830 – pskink Jul 26 '22 at 08:57
  • pskink Thatnk you , now I understand! for Loop goes sync without async word so it will wait everything inside. That's awesome! Thank you very much! – David Jul 26 '22 at 09:00
  • so how come it didn't work with `for(final item in ...)`? – pskink Jul 26 '22 at 09:34
  • it worked I just had async with it. for without async and function with await works fine, so you were right from the beginning it was just my fault, and then when you showed me the link I read everything clearly and set everything the correct way . Thank you again :) – David Jul 26 '22 at 11:23

1 Answers1

0

You can separate the refreshing data part to another function.

// Just need to check _rawJsonListE is empty or not
_isNeedUpdate = _rawJsonListE.isNotEmpty();

Create a new function.

Future<List<String>> checkDataAndRefresh(List<String> _rawJsonListE) async {
  List<String> rawJsonListNEW = [];
  _rawJsonListE!.forEach((item) async {         
     if (someCondition with item Data) {
        final String newString = await makeHttpCallFutureAwaitFunction(item);
        rawJsonListNEW.add(newString);
     } else {
       rawJsonListNEW.add(item);
     }
  });
  return rawJsonListNEW;
}

And if _isNeedUpdate is true, do work.

if (_isNeedUpdate) 
  final List<String> newData = await checkDataAndRefresh(_rawJsonListE);
  prefs.setStringList('storedData', newData);
Yii Chen
  • 39
  • 3
  • Didn't quite get that, Can you please explain more and make code look more complete? – David Jul 26 '22 at 08:53
  • Yii Chen thanks for helping but I've solved the problem with pskink advice to use for loop. It works perfectly. Thanks for the help anyway! – David Jul 26 '22 at 09:01