简体   繁体   中英

flutter_bloc share state for many blocs

let's say I want to check for internet connection every time I call Api, if there's no internet the call with throw exception like NoInternetException and then show a state screen to the user tells him to check their connection.

How can I achieve that without creating a new state for every bloc in flutter_bloc library?

You can do this in the bloc that manages your root pages like authentication_page and homepage.

Create a state for noConnectivity.

NoConnectivity extends AuthenticationState{
  final String message;

  const NoConnectivity({ this.message });

}

Now create an event for noConnectivity.

NoConnectivityEvent extends AuthenticationEvent{}

Finally, create a StreamSubscription in your AuthenticationBloc to continuously listen to connecitvityState change and if the state is connectivity.none we'll trigger the NoConnecitivity state.

class AuthenticationBloc
    extends Bloc<AuthenticationEvent, AuthenticationState> {

StreamSubscription subscription;

 @override
  AuthenticationState get initialState => initialState();

  @override
  Stream<AuthenticationState> mapEventToState(
    AuthenticationEvent event,
  ) async* {
    // ... all other state map
   else if(event is NoConnectivityEvent) {
     yield* _mapNoConnectivityEventToState();
   }


Stream<AuthenticationState> _mapNoConnectivityEventToState() async * {
     subscription?.cancel();

     //Edit to handle android internet connectivity.
      subscription = Connectivity()
                    .onConnectivityChanged
                    .listen((ConnectivityResult result) {
                         if(Platform.isAndroid) {
                              try {
                                     final lookupResult = InternetAddress.lookup('google.com');
                                     if (lookupResult.isNotEmpty && lookupResult[0].rawAddress.isNotEmpty) {
                                         print('connected');
                                    }
                                  } on SocketException catch (error) {
                                       return add(NoConnectivityState(message: error.message ));
                                  }
                          } else if(result == ConnectivityResult.none ) {
                            return add(NoConnectivityState(message: "Noconnection")) ;

                          }
                           print("Connected");

                    });
}

  @override
  Future<void> close() {
    subscription?.cancel();
    return super.close();
  }

}

This subscription Stream will forever listen to a no connection and push the appropriate page you like to the state.

Required packages

rxdart

connectivity

Hope it helps!

you need base class bloc let's say his name "BaseBloc" and he shall inherit from the "Bloc" class, and implement "mapToStateEvent" method to process "noInternet" exception, and after that call method let's say his name "internalMapToStateEvent" you created, this method it's override method, and inherited all your bloc class from "BaseBloc" and you need same that for pages to draw one widget "noInternetWidget"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM