Home > other >  Dart cannot break out of loop while inside awaited then callback
Dart cannot break out of loop while inside awaited then callback

Time:12-20

I'm trying to generate random int and check if the integer is exists in Firebase database, and do this infinitly until the integer is not exist inside database.

Below my code:

while (true) {
  _changeRandomInt()
  firebaseFirestore.collection("myCollection").doc(_randomInt).get().then((DocumentSnapshot documentSnapshot) {
  if (getFromFirebase(documentSnapshot) == null) {
    break;
  }
  });
}

But I cannot even run this code. Error: A break statement can't be used outside of a loop or switch statement. Try removing the break statement. I have my break inside while loop, then why I'm getting this error? How to fix this?

CodePudding user response:

A break statement can't be used outside of a loop or switch statement. Try removing the break statement.

This is self explanatory. You can't use break outside of a loop. Which in your case is inside a future.

Do something like this:

_changeRandomInt();
firebaseFirestore.collection("myCollection").doc(_randomInt).get()
    .then((DocumentSnapshot documentSnapshot) {

    while (getFromFirebase(documentSnapshot) != null){
        //the body of this loop will only execute as long as the value isn't null
        //will break out of the loop as soon as the value is null
    }
}

CodePudding user response:

The break you have used is inside then(), which means no loop is available immediately above `break. You can refactor your code in this manner to get it working.

while (true) {
  _changeRandomInt()
  final documentSnapshot = await firebaseFirestore.collection("myCollection").doc(_randomInt).get();
  if (getFromFirebase(documentSnapshot) == null) {
    break;
  }
}

If getFromFirebase is also a future, then await that as well inside if block.

CodePudding user response:

You want to do something like this:

void functionName() async {
  try{
    var ans;
    while(getFromFirebae(ans)== null){
     ans = await firebaseFirestore.collection("myCollection").doc(_randomInt).get();
    
    }
  } catch(e){
    //error
  }
}

However, this is not the correct way. A good practice is to create a loading widget, that would show an animation while the future is loading. An even better way - to load everything in the background without stalling the overall app.

CodePudding user response:

Some people have been saying that you're using "break inside a Future", but that's not quite right. Your problem is that you're using break inside of a separate function body. This is equivalent to writing:

void f() {
  break;
}

which doesn't make sense since break is not used directly within a local loop or switch statement. It doesn't matter that you're creating your function within a loop; break and continue statements perform local control flow (within a function), not across functions.

In general, instead of using Future.then, you should prefer using async/await which will have the compiler generate the callback function with appropriate code transformations for you:

while (true) {
  _changeRandomInt()

  var documentSnapshot =
    await firebaseFirestore.collection("myCollection").doc(_randomInt).get();
  if (getFromFirebase(documentSnapshot) == null) {
    break;
  }
}

Note that performing an asynchronous operation continuously in a loop isn't very efficient, so you probably should consider alternative approaches if possible, however.

  • Related