Dart/Flutter - yield from callback function
Asked Answered
A

1

5

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;
}
Actinozoan answered 19/7, 2019 at 6:5 Comment(0)
L
7

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);
}

Lead answered 20/7, 2019 at 1:22 Comment(2)
That's a nice solution, I solved it by wrapping my store.dispatch function which returns me a Future, And awaiting that future I'm able to yield after that.Actinozoan
In flutter_bloc v1.0.0 or later you should use add() method instead of dispatch() method.Rising

© 2022 - 2024 — McMap. All rights reserved.