Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dart/Flutter - yield from callback function

I need to make a function call which does not return anything (void). Only way to get notified about function completion is sending a callback function.
Now I an using BLoC pattern along with ReDux, When an event is dispatched, I dispatch another action to store of redux, After action is completed it calls the callback function. And now inside callback function, I want to update the state of bloc. Below is my implementation,

if (event is Login) {
  yield currentState.copyWith(formProcessing: true);
  store.dispatch(authActions.login(
    currentState.username,
    currentState.password,
    (error, data) {
      print(error);
      print(data);
      // I want to yield here.
      yield currentState.copyWith(formProcessing: false);
    },
  ));
}

As shown in the above code snippet, Inside the callback function, I want to yield.

Solution

Create a function that returns the future and makes callback function to store dispatch, Heres sample.

if (event is Login) {
  yield currentState.copyWith(formProcessing: true);

  try {
    dynamic result = await loginAction(store, currentState.username, currentState.password);
    print(result);
    yield currentState.copyWith(formProcessing: false);
  } catch (e) {
    print(e);
  }
}

Future loginAction(store, username, password) {
  var completer = new Completer();

  store.dispatch(authActions.login(
    username,
    password,
    (error, data) {
      if (error != null) {
        completer.completeError(error);
      } else if (data != null) {
        completer.complete(data);
      }
    },
  ));

  return completer.future;
}
like image 207
Mehul Prajapati Avatar asked Jul 19 '19 06:07

Mehul Prajapati


1 Answers

You need to create other event, and dispatch this event in your callback function, then you can do what you want in the function that filter your events.

I don't know what is the purpose of your BLoC, but the name of this event depends on the use case, it can be UpdateForm, UpdateState, LoggedIn,LoggedOut, etc. You will find the most descriptive name for your use case.

Remember that you can also create this event with parameters, for example UpdateForm (bool isLoggedIn), and yield different states according to your conditions.

For the example, the name of this event is OtherEvent.

if (event is Login) {
  yield currentState.copyWith(formProcessing: true);
  store.dispatch(authActions.login(
    currentState.username,
    currentState.password,
    (error, data) {
      print(error);
      print(data);

      dispatch(OtherEvent());
    },
  ));
} else if (event is OtherEvent) {
   // You can yield here what you want
   yield currentState.copyWith(formProcessing: false);
}

like image 143
GiancarloCode Avatar answered Oct 23 '22 04:10

GiancarloCode