Reset values event and state in the bloc flutter
BLoC
design pattern helps separate the presentation layer from the business logic.
Events
are the input to a Bloc. They are commonly UI events such as button presses. Events are dispatched and then converted to States.
States
are the output of a Bloc. Presentation components can listen to the stream of states and redraw portions of themselves based on the given state.
Transitions
occur when an Event is dispatched after mapEventToState
has been called but before the Bloc's state has been updated. A Transition consists of the currentState, the event which was dispatched, and the nextState.
Coming to the example you shown, you have having 2 button in UI:
btn : You are triggering an event DataEvent_name by passing only Name argument as "mohammd". Hence, a final state is having a value as name:'mohammd' and pass:''. Since you are printing the current state value, hence the output is :
a:mohammd b:
pass: You are triggering an event DataEvent_name by passing only pass argument as "passsss". Hence, a final state is having a value as name: '' and pass:'passsss'. Since you are printing the current state value, hence the output is :
a: b:passsss
Are the states and event in the block reset in each change of its values
Event are just the input. It is a carrier of data from UI so that required data is available while doing a business logic. As state are the output of an event, in the entire BLoC it can have only one state at a time. Hence, yes it will update the earlier state. It depends on the use case if we want to reset entirely or update certain values in the existing state.
How to update existing state
In mapEventToState
, we are having access to the current state using state
variable. So while yielding a new state, we can pass the data from current state as well based on the required use case.
In your example: If you want to maintain the old value of name & pass if its blank:
yield DatatestState(
name: event.name == '' ? state.name : event.name,
pass: event.pass == '' ? state.pass : event.pass);
It will return the below output:
a:mohammd b:
a:mohammd b:passsss
Mohammad Soleymani
Updated on December 31, 2022Comments
-
Mohammad Soleymani over 1 year
I give the values to the event individually, but the values of the other variables are reset in the event. I did the same for the state. I defined a state with two variables that I gave to those values by copyWith in different places But every time an ion is sent, the state values return to their original state. Are the states and event in the block reset in each change of its values ????
main
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:test1/bloc/datatest_bloc.dart'; import 'package:test1/bloc/datatest_state.dart'; import 'package:test1/bloc/datatest_event.dart'; import 'bloc/datatest_bloc.dart'; main() { runApp(MaterialApp( home: BlocProvider<Databloc>( create: (context) => Databloc(), child: Home(), ), )); } class Home extends StatefulWidget { const Home({Key? key}) : super(key: key); @override _HomeState createState() => _HomeState(); } class _HomeState extends State<Home> { @override Widget build(BuildContext context) { return Scaffold( body: BlocBuilder<Databloc, DatatestState>( builder: (context, state) { return Center( child: Column( children: [ ElevatedButton( onPressed: () { BlocProvider.of<Databloc>(context) .add(DataEvent_name().copyWith(name: 'mohammd')); }, child: Text('btn'), ), ElevatedButton( onPressed: () { BlocProvider.of<Databloc>(context) .add(DataEvent_name().copyWith(pass: 'passsss')); }, child: Text('pass'), ), ], ), ); }, ), ); } }
event-bloc
} class DataEvent_name extends DatatestEvent { final String name; final String pass; DataEvent_name({ this.name='', this.pass=''}); DataEvent_name copyWith({String? name, String? pass}) { return DataEvent_name(name: name ?? this.name, pass: pass ?? this.pass); } } class DataEvent_pass extends DatatestEvent {} class DataEvent_print extends DatatestEvent {}
state-class
class DatatestState { final String name; final String pass; DatatestState({ this.name ='', this.pass='', }); DatatestState copyWith({ String? name, String? pass, }) { return DatatestState( name: name ?? this.name, pass: pass ?? this.pass, ); } }
bloc-class
class Databloc extends Bloc<DatatestEvent, DatatestState> { Databloc() : super(DatatestState()); final servisApi = ServisApi(); @override Stream<DatatestState> mapEventToState(DatatestEvent event) async* { if (event is DataEvent_name) { yield DatatestState(name: event.name, pass: event.pass); servisApi.PrintState(a: state.name, b: state.pass); } } }
outpout
flutter: a:mohammd b: flutter: a: b:passsss flutter: a:mohammd b: flutter: a: b:passsss flutter: a:mohammd b: flutter: a: b:passsss
-
NelsonThiago almost 3 yearsAre you using equatable ?
-
Mohammad Soleymani almost 3 yearsYes ... but the presence of the problem was not solved
-
NelsonThiago almost 3 yearsI asked that because I don't see you overwriting the properties, this could make the bloc not update properly.
-
Mohammad Soleymani almost 3 yearsNow I tested again and two events each change the value of the variable within the state and I used the package equatable but again when I change the value of the state variable with one of the events the other variable to the state
-