I have been working with Spring Boot and Flutter. I have 3 lists in which ingredient, unit, and quantity stored for each ingredient. I need that when the user press save
button a loop iterate among the 3 lists and get the ith index value and store in Database by hiting the URL.
var unCheckedIngredients = [], unCheckedUnits = [], unCheckedQuantities = [];
onPressed: () {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
for (int i=0;i<unCheckedQuantities.length;i++)
{
insertUserIngredient(unCheckedIngredients[i]);
insertUserUnit(unCheckedUnits[i]);
insertUserQuantity(unCheckedQuantities[i]);
}
setState(() {
_formKey.currentState.reset();
displayChipList.clear();
});
}
},
As the 3 functions are being called. So, it should work sequentially but in DART I don't what the problem is it request the 2nd instruction first and the 1st line afterward randomly. It should work sequentially.
Let say, if the unCheckedQuantities. length = 2
- It is executing the first line in for loop 2 times and then the 2nd line twice and so on.
Error
/flutter (12297): GET http://10.0.2.2:8085/user/ingredient/quantity?ingredient_quantity=3 I/flutter (12297): qauntity = {"timestamp":"2020-04-02T15:29:54.030+0000","status":500,"error":"Internal Server Error","message":"query did not return a unique result: 2; nested exception is javax.persistence.NonUniqueResultException: query did not return a unique result: 2","path":"/user/ingredient/quantity"} E/FirebaseInstanceId(12297): Token retrieval failed: AUTHENTICATION_FAILED
I hope you're not mutating the quantity list while it's interating. If that isn't the case, are the insert functions doing anything asynchronously? Then you need to specifically tell Dart compiler to stop with the await keyword. Even if they aren't you can still use them to execute your process synchronously but it isn't a good idea when you're doing some heavy computation
For this, your function must return a Future
void insertSomething(){}
To
Future<void> insertSomething(){}
and change your onPressed method to
() async {
if (...) {
for (...) {
await insertSomething()
}
}
}
The thing is Dart works similar to Node-JS in a non-blocking way, so the asynchronous events can complete on their own time and when they are done they will be added to the event queue and the event loop will pick it up in the next cycle.
Now when you don't want this behavior you use async/await, to force the event loop to wait for a specific to get processed. You can take a look at below dartpad, first run it normally and then try removing the await keywords from the results()