5

I was developing an application in flutter which does OTP based authentication to log in. Earlier I was managing the states in the class itself so that I can use the setState method to render the UI accordingly. Then I changed into flutter_bloc cubit pattern to manage the states. But I fail to understand that how can I keep track of multiple states in one cubit.

Consider the following code of State and Cubit,


**State**.

@immutable
abstract class LoginState {}

class LoginInitial extends LoginState {
  final Map loginState;
  LoginInitial({this.loginState});
}

**Cubit**
class LoginCubit extends Cubit<LoginState> {
  Map loginState = {
    "isPhoneSubmitted": false,
    "isOtpArrived": false,
  };
  LoginCubit()
      : super(
          LoginInitial(
            loginState: {
              "isPhoneSubmitted": false,
              "isOtpArrived": false,
            },
          ),
        );

  void sendOtp() {
    emit(
      LoginInitial(
        loginState: {
          "isPhoneSubmitted": true,
          "isOtpArrived": false,
        },
      ),
    );
    Future.delayed(Duration(seconds: 4), () {
      emit(
        LoginInitial(
          loginState: {
            "isPhoneSubmitted": true,
            "isOtpArrived": true,
          },
        ),
      );
    });
  }
}

Here, Initially, I'm setting both values inside the map as false. And when the user clicks on the button setting the isPhoneSubmitted to true. And a few seconds later isOtpArrived to true(In future after getting OTP). However, I don't think this is the right approach to implement the pattern. Consider If I have 10 properties in a class and I'm sending a map of 10 properties each time when emit method is called.

Can someone help me understand or implement the best practice to hold/update multiple states to the widget the Cubit is listening to?

Also, in the widget, this is how I'm listening to the changes,

 BlocBuilder<LoginCubit, LoginState>(builder: (context, state) {
                final data = (state as LoginInitial).loginState;
                if (!data["isPhoneSubmitted"]) {
                  return phoneNumberSubmitWidget();
                } else {
                  return codeVerificationWidget();
                }
              }),
Musthafa
  • 87
  • 1
  • 2
  • 6
  • 2
    As you said this is not a right approach. Go thorough https://bloclibrary.dev/#/gettingstarted and the tutorials for better understanding of the bloc state management – krishnakumarcn May 25 '21 at 07:51
  • you can listen to the state in the builder function. change your if statement to `(state is MyState)` after that the builder should get updated when the state changes. If that answers your question? – SilkeNL May 25 '21 at 07:54
  • Thank you for your comment @SilkeNL. If I use the state is MyState approach which can actually have one state manipulated in different state classes. Even then how can I keep track of multiple state values. If I manipulate one property next time it changes to another. – Musthafa May 25 '21 at 07:56
  • as @nvoigt 's answer says, it might be better to use Bloc instead of Cubit. Then you can `yield` different states. Change back and forth between maybe a loading and loaded state. Then your widget will be updated every state change. – SilkeNL May 25 '21 at 08:27
  • Yes, @SilkeNL. I have gone through and going to implement the bloc itself. Actually, I'm using the flutter_bloc library. In their documentation, only a cubit example is there. I was following so many guides and very much confused. Even for bloc, many are using flutter_bloc and many are directly writing from scratch. It's actually so much confusing that my app will go very complex in future. – Musthafa May 25 '21 at 08:35
  • Do you have a chat program where I can send you some sample code? – SilkeNL May 25 '21 at 08:38
  • yeah ... no, lol, not whatsapp. Maybe something like discord? My user is: SilkeNL#2967 (And I would edit your comment to not add your phone number) – SilkeNL May 25 '21 at 09:13
  • Oh my bad. I have created an account in discord. My user is : musthafapa7#2539 – Musthafa May 25 '21 at 09:30

1 Answers1

8

However, I don't think this is the right approach to implement the pattern.

You are correct. The first step for complex state switches is to not use Cubit but an actual Bloc. Cubits are meant for very simple data with basically no state flow logic at all. Like an int. Or maybe a DarkTheme/LightTheme switch. Or maybe the language, where it can only ever be one and exactly one.

But you have a complex flow. With "in-between" states. So use a Bloc and read the tutorial on this, in this case probable the login tutorial.

nvoigt
  • 75,013
  • 26
  • 93
  • 142
  • 1
    Thanks, @nvoigt for the suggestion. I'm trying to implement the bloc itself instead of using cubits. However, the above example is very complex and will lead me to have a lot of boiler plate codes. If possible can you provide me with an example that uses the flutter_bloc library in an easy way. – Musthafa May 25 '21 at 08:37