Home > Blockchain >  How to call a method from Bloc on button click?
How to call a method from Bloc on button click?

Time:06-21

I am using Bloc to check internet connection. If there is no connection, I show the SnackBar. But I also need to be able to reuse the connection method to re-check the connection by clicking on the button, but I don’t understand how to call this method. Tell me how to call the connection method when the button is clicked?

bloc

class ConnectedBloc extends Bloc<ConnectedEvent, ConnectedState> {
  StreamSubscription? subscription;

  ConnectedBloc() : super(ConnectedInitial()) {
    on<OnConnectedEvent>((event, emit) => emit(ConnectedSucess()));
    on<OnNotConnectedEvent>((event, emit) => emit(ConnectedFailure()));

    void connection() => Connectivity()
        .onConnectivityChanged
        .listen((ConnectivityResult result) {
      if (result == ConnectivityResult.wifi ||
          result == ConnectivityResult.mobile) {
        add(OnConnectedEvent());
      } else {
        add(OnNotConnectedEvent());
      }
    });

home

home: BlocConsumer<ConnectedBloc, ConnectedState>(
          listener: ((context, state) {
            if (state is ConnectedSucess) {
              const SizedBox();
            } else if (state is ConnectedFailure) {
              ScaffoldMessenger.of(context).showSnackBar(
                SnackBar(
                  duration: const Duration(seconds: 3),
                  backgroundColor: Colors.transparent,
                  elevation: 0,
                  content: SystemMessagesSnackBar(
                    message: 'No internet access. Check your connection',
                    textButton: 'Refresh',
                    onPressed: () =>
                        ScaffoldMessenger.of(context).hideCurrentSnackBar(),
                    icon: SvgPicture.asset(constants.Assets.no_connection),
                  ),
                ),
              );
            }
          }),

CodePudding user response:

  1. wrap the code with a streambuilder and then associate the bloc streams with the streambuilder
  2. in your button click event interact with the bloc class
  3. check the streambuilder state and process the returning data.

yaml

dependencies:
  flutter:
    sdk: flutter
  equatable: ^2.0.3  
  rxdart: ^0.27.4   

import 'package:flutter/material.dart';
import 'package:equatable/equatable.dart';
import 'package:rxdart/rxdart.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Button Stream',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Test_StreambuilderButton(),
    );
  }
}
class Test_StreambuilderButton extends StatefulWidget {
  Test_StreambuilderButton({Key? key}) : super(key: key);
  BlocCode bloc= new BlocCode();
  @override
  State<Test_StreambuilderButton> createState() => _Test_StreambuilderButtonState();
}

class _Test_StreambuilderButtonState extends State<Test_StreambuilderButton> {
  @override
  Widget build(BuildContext context) {
    return
    Scaffold(appBar: AppBar(title:Text("Button Stream Event")),
    body:
    Column(children: [
    StreamBuilder<BlocState>(
      stream: widget.bloc.blocStream,
      builder:(context,snapshot)
      {
        if (snapshot.hasData)
        {
            String data=snapshot.data!._message;
            if (data == null)
            {
                return (Container(child:Text("No data")));    
            }
            return (Container(child:Text(data)));
            
        }
        else
        {
          return (Container(child:Text("No activity")));
        }
      }
      
    ),
    ElevatedButton(onPressed:(){
      widget.bloc.setMessage(BlocState("Hello World"));
    }, child: Text("Press Me"))
    ]));
     
  }
}

class BlocState extends Equatable
{
    BlocState(this._message);
    final String _message;
    @override
  List<Object> get props=>[_message];
  String get getMessage {return _message;}

}
class BlocCode
{
  BlocCode();
  Stream<BlocState> get blocStream => _loadController.stream;
  final _loadController=BehaviorSubject<BlocState>();

void dispose()
  {
    _loadController.close();
  }

  setMessage(BlocState state)
  {
    _loadController.sink.add(state);  
  }
}

CodePudding user response:

To call a method inside your bloc, you need to get a reference to your bloc first by using context.read<T>(). In your case:

context.read<ConnectedBloc>()

You can then call the method as follows:

onPressed:(){
  ScaffoldMessenger.of(context).hideCurrentSnackBar();
  context.read<ConnectedBloc>().connection();
}

But this will create an additional stream. Maybe you should use checkConnectivity if you click on the button.

  • Related