samedi 1 juillet 2023

listener is not listening to states in bloc consumer in flutter bloc

The problem is that the listener in the BlocConsumer widget, implemented using the bloc package in a Flutter application, is not working as expected. Despite setting up the BlocProvider correctly and implementing the listener, the desired navigation functionality based on the emitted states is not taking place. Specifically, when the AuthenticatedState is emitted, the application should navigate to the home page, and when the UnAuthenticatedState is emitted, it should navigate to the login page. However, the navigation is not occurring as intended. Troubleshooting steps have been undertaken, including checking for errors, adding debug statements, and reviewing the bloc implementation, but the root cause of the issue remains unidentified. Further investigation and seeking assistance from the Flutter community may be necessary to rectify the problem and ensure proper navigation based on the emitted states.

Flutter

import 'package:flutter/material.dart';
import 'package:bloc/bloc.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:practice_clean_architecture/dependancy_injection.dart';
import 'package:practice_clean_architecture/features/splash_screen/presentation/widgets/splash_widget.dart';
import 'package:practice_clean_architecture/features/user_home_page/presentation/widgets/home.dart';
import '../../../user_login/presentation/pages/user_login_page.dart';
import '../bloc/bloc.dart';
import '/utils/show_progress.dart';

class SplashPage extends StatefulWidget {
  const SplashPage({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return _SplashPageState();
  }
}

class _SplashPageState extends State<SplashPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _buildSplashPage(context),
    );
  }

  BlocProvider<AuthenticationBloc> _buildSplashPage(BuildContext context) {
    return BlocProvider(
      create: (_) => getItServiceLocator<AuthenticationBloc>(),
      child: BlocConsumer<AuthenticationBloc, AuthenticationState>(
        listener: (context, state) {
          if (state is InitialState) {
            BlocProvider.of<AuthenticationBloc>(context)
                .add(AuthenticateUserEvent("hello"));
          } else if (state is AuthenticatedState) {
            print("object");
            Navigator.of(context).pushAndRemoveUntil(
                MaterialPageRoute(builder: (context) => Home()),
                (route) => false);
          } else if (state is UnAuthenticatedState) {
            print("object");
            Navigator.of(context).pushAndRemoveUntil(
                MaterialPageRoute(builder: (context) => LoginScreen()),
                (route) => false);
          } else {
            print("object");
          }
        },
        builder: (context, state) {
          return SplashScreen();
        },
      ),
    );
  }
}

class SplashScreen extends StatefulWidget {
  SplashScreen({Key? key, this.title}) : super(key: key);

  final String? title;

  @override
  _SplashScreenState createState() {
    return _SplashScreenState();
  }
}

class _SplashScreenState extends State<SplashScreen> {
  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: const BoxDecoration(
        gradient: LinearGradient(
          colors: [
            Colors.white,
            Colors.grey,
            Colors.black,
          ],
          begin: FractionalOffset(0, 0),
          end: FractionalOffset(1.0, 0.0),
          stops: [
            0.0,
            0.5,
            1.0,
          ],
          tileMode: TileMode.clamp,
        ),
      ),
      child: AnimatedOpacity(
        opacity: 0.7,
        duration: const Duration(milliseconds: 1200),
        child: Center(
          child: Container(
            height: 140.0,
            width: 140.0,
            decoration: BoxDecoration(
              shape: BoxShape.rectangle,
              color: Colors.transparent,
              boxShadow: [
                BoxShadow(
                  color: Colors.blue.withOpacity(0.3),
                  blurRadius: 2.0,
                  offset: const Offset(5.0, 3.0),
                  spreadRadius: 2.0,
                )
              ],
            ),
            child: const Center(
              child: ClipRect(
                child: Image(
                  image: AssetImage(
                    "assets/images/motorcycle.png",
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

@immutable
abstract class AuthenticationEvent extends Equatable {
  AuthenticationEvent();

  @override
  List<Object> get props => [];
}

@immutable
class AuthenticateUserEvent extends AuthenticationEvent {
  final String user;
  AuthenticateUserEvent(this.user);

  @override
  List<Object> get props => [
        user,
      ];
}

@immutable
abstract class AuthenticationState extends Equatable {
  AuthenticationState();

  @override
  List<Object> get props => [];
}

@immutable
class InitialState extends AuthenticationState {
  final String initialMessage;
  InitialState(this.initialMessage);

  @override
  List<Object> get props => [
        initialMessage,
      ];
}

@immutable
class InProgressState extends AuthenticationState {
  final String progressMessage;
  InProgressState(this.progressMessage);

  @override
  List<Object> get props => [
        progressMessage,
      ];
}

@immutable
class AuthenticatedState extends AuthenticationState {
  final String authenticationMessage;
  AuthenticatedState(this.authenticationMessage);

  @override
  List<Object> get props => [
        authenticationMessage,
      ];
}

@immutable
class UnAuthenticatedState extends AuthenticationState {
  final String unauthenticationMessage;
  UnAuthenticatedState(this.unauthenticationMessage);

  @override
  List<Object> get props => [
        unauthenticationMessage,
      ];
}

@immutable
class ErrorState extends AuthenticationState {
  final String errorMessage;
  ErrorState(this.errorMessage);

  @override
  List<Object> get props => [
        errorMessage,
      ];
}

class AuthenticationBloc
    extends Bloc<AuthenticationEvent, AuthenticationState> {
  GetUserAuthenticate getUserAuthenticate;

  AuthenticationBloc({GetUserAuthenticate? getUserAuthenticate})
      : assert(getUserAuthenticate != null),
        getUserAuthenticate = getUserAuthenticate!,
        super(InitialState("Authentication Started")) {
    on<AuthenticateUserEvent>((event, emit) async {
      print("object");
      emit(InProgressState("Authenticating"));
      final authenticated =
          await getUserAuthenticate(const AuthenticationParams());
      authenticated.fold(
        (failure) => emit(
          UnAuthenticatedState("UnAuthorized"),
        ),
        (success) => emit(
          AuthenticatedState("Authorized"),
        ),
      );
    });
  }
}

I implemented a BlocConsumer widget in my Flutter application to observe state changes in the AuthenticationBloc. By wrapping it with a BlocProvider, I expected the application to navigate to the home page when an AuthenticatedState was emitted and to the login page when an UnAuthenticatedState was emitted. I added the necessary navigation logic inside the listener callback. However, despite my efforts to troubleshoot the issue, including checking for errors, adding debug statements, and reviewing the code, the expected navigation did not occur. The application either remained on the splash screen or did not navigate to the desired pages. Identifying the root cause proved challenging. As a result, the navigation functionality based on the emitted states did not work as intended. Further investigation and seeking help from the Flutter community may be necessary to resolve the issue and achieve the desired navigation behavior.

Aucun commentaire:

Enregistrer un commentaire