Search code examples
flutterdartbloc

How to send data to bloc in flutter


I'm trying to learn Bloc state management and developing a simple app to learn. when the user types anything in a TextField that text will be displayed under the field.

enter image description here

and now I'm sending the text field controller to the bloc file by declaring the controller globally.

final textController = TextEditingController();

but I want to know if there is any way to send the controller value to the bloc file from UI code (without global declaring)


Solution

  • Please refer to the below code

    flutter_bloc: 7.0.1

    Solution 1

    Bloc Class

    import 'package:bloc/bloc.dart';
    import 'package:meta/meta.dart';
    
    part 'demo_event.dart';
    part 'demo_state.dart';
    
    class DemoBloc extends Bloc<DemoEvent, DemoState> {
      DemoBloc() : super(DemoNoInputState());
    
      @override
      Stream<DemoState> mapEventToState(DemoEvent event) async* {
        if (event is GetInput) {
          yield* _mapGetInputEventToState(event);
        }
      }
    
      Stream<DemoState> _mapGetInputEventToState(GetInput event) async* {
        // showInputfromBloc() {
        //   // Call an API
        // }
    
        // showInputfromBloc();
    
        yield DemoInitial(inputText: event.inputText);
      }
    }
    
    

    Event Class

    part of 'demo_bloc.dart';
    
    @immutable
    abstract class DemoEvent {}
    
    class GetInput extends DemoEvent {
      String inputText;
    
      GetInput(this.inputText);
    }
    
    
    

    State

    part of 'demo_bloc.dart';
    
    @immutable
    abstract class DemoState {}
    
    class DemoInitial extends DemoState {
      String? inputText;
    
      DemoInitial({this.inputText});
    }
    
    class DemoNoInputState extends DemoState {}
    
    
    class _MyHomePageState extends State<MyHomePage> {
      final DemoBloc demoBloc = DemoBloc();
    
      TextEditingController textEditingController = TextEditingController();
    
      @override
      void initState() {
        super.initState();
      }
    
      @override
      void dispose() {
        demoBloc.close();
        textEditingController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Padding(
            padding: const EdgeInsets.all(15.0),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                const Text(
                  'Enter Input',
                ),
                TextField(
                  controller: textEditingController,
                  decoration: const InputDecoration(
                    border: OutlineInputBorder(),
                    labelText: 'Input',
                    hintText: 'Enter Input',
                  ),
                ),
                BlocBuilder<DemoBloc, DemoState>(
                  bloc: demoBloc,
                  builder: (context, state) {
                    if (state is DemoInitial) {
                      return Text(
                        '${state.inputText}',
                        style: Theme.of(context).textTheme.headline4,
                      );
                    } else if (state is DemoNoInputState) {
                      return const SizedBox.shrink();
                    } else {
                      return const SizedBox.shrink();
                    }
                  },
                ),
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              demoBloc.add(GetInput(textEditingController.text));
            },
            child: const Center(child: Text("Result")),
          ),
        );
      }
    }
    
    
    

    Solution 2

    Reult

    
    class _MyHomePageState extends State<MyHomePage> {
      final DemoBloc demoBloc = DemoBloc();
    
      TextEditingController textEditingController = TextEditingController();
    
      @override
      void initState() {
        super.initState();
      }
    
      @override
      void dispose() {
        demoBloc.close();
        textEditingController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Padding(
            padding: const EdgeInsets.all(15.0),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                const Text(
                  'Enter Input',
                ),
                BlocBuilder<DemoBloc, DemoState>(
                  bloc: demoBloc,
                  builder: (context, state) {
                    if (state is DemoInitial) {
                      return Column(
                        children: [
                          TextField(
                            controller: textEditingController,
                            decoration: const InputDecoration(
                              border: OutlineInputBorder(),
                              labelText: 'Input',
                              hintText: 'Enter Input',
                            ),
                            onChanged: (value) {
                              demoBloc.add(GetInput(textEditingController.text));
                            },
                          ),
                          if (textEditingController.text.isNotEmpty)
                            Text(
                              '${state.inputText}',
                              style: Theme.of(context).textTheme.headline4,
                            ),
                        ],
                      );
                    } else {
                      return const SizedBox.shrink();
                    }
                  },
                ),
              ],
            ),
          ),
        );
      }
    }
    
    
    

    Bloc Class

    import 'package:bloc/bloc.dart';
    import 'package:meta/meta.dart';
    
    part 'demo_event.dart';
    part 'demo_state.dart';
    
    class DemoBloc extends Bloc<DemoEvent, DemoState> {
      DemoBloc() : super(DemoInitial());
    
      @override
      Stream<DemoState> mapEventToState(DemoEvent event) async* {
        if (event is GetInput) {
          yield* _mapGetInputEventToState(event);
        }
      }
    
      Stream<DemoState> _mapGetInputEventToState(GetInput event) async* {
        yield DemoInitial(inputText: event.inputText);
      }
    }
    
    
    

    State

    part of 'demo_bloc.dart';
    
    @immutable
    abstract class DemoState {}
    
    class DemoInitial extends DemoState {
      String? inputText;
    
      DemoInitial({this.inputText});
    }