Search code examples
apiflutterdartlogic

How do i call get request just after login in flutter?


I'm stuck and could not think about the solution and logic. I have this scenario where a user is logged in I need to fetch profile data according to the userID of the logged-in user. So that I can fetch user details and show in the app.

I'm using flutter bloc. Where and when should I call the API?? I tried it just after the login event and also tried it calling in init() but could not figure out the actual logic of doing it.

I'm very confused. Please help me explain logic to this flow.


Solution

  • Hey when user is logged in save his profileID in secure storage, after that push new screen (main screen for example and in init state download your profile)

    Login bloc:

    class LoginBloc extends Bloc<LoginEvent, LoginState> {
      Api _repository;
      TokenManager _tokenManager;
    
      LoginBloc({
        @required Api repository,
        @required TokenManager tokenManager
      })  : assert(repository != null),
            assert(tokenManager != null),
            _repository = repository,
            _tokenManager = tokenManager;
    
      @override
      LoginState get initialState => LoginState.empty();
    
       @override
       Stream<LoginState> mapEventToState(LoginEvent event) async* {
         if (event is LoginWithCredentialsPressed) {
            yield* _mapLoginWithCredentialsPressedToState(
             login: event.login,
              password: event.password,
            );
         }
       }
       Stream<LoginState> _mapLoginWithCredentialsPressedToState({
         String login,
         String password,
       }) async* {
         yield LoginState.loading();
        try {
          LoginResponse loginResponse = await _repository.login(login, password, password);
          await _tokenManager.setToken(loginResponse.token);
          await _tokenManager.setRefreshToken(loginResponse.refresh_token);
          yield LoginState.success();
        } catch (_) {
          yield LoginState.failure();
        }
      }
    }
    

    then in view add code like, please notice, it's not full code, I removed some parts

     @override
     Widget build(BuildContext context) {
       return BlocListener<LoginBloc, LoginState>(listener: (context, state) {
         if (state.isSuccess) {
           Navigator.pushReplacementNamed(context, '/main'); 
         }
       }, child: BlocBuilder<LoginBloc, LoginState>(builder: (context, state) {
      return Padding(
        padding: EdgeInsets.all(20),
        child: Form(
          child: ListView(
            children: <Widget>[
              Padding(
                padding: EdgeInsets.symmetric(vertical: 20),
                child: SvgPicture.asset(
                  'assets/logo.svg',
                  width: MediaQuery
                      .of(context)
                      .size
                      .width,
                  height: 150,
                ),
              ),
            ],
          ),
        ),
      );
    }));
    

    So push your main bloc and override it's initState() like (it's your widget)

      @override
      void initState() {
        super.initState();
        _menuBloc = BlocProvider.of<MenuBloc>(context);
        _menuBloc.add(ModuleInitialized());
      }
    

    And in your bloc file add code to download your data. If you have some questions feel free to ask)