Mohammad Soleymani
Mohammad Soleymani

Reputation: 52

Reset values event and state in the bloc flutter

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

Upvotes: 1

Views: 4081

Answers (1)

Nirdesh Sharma
Nirdesh Sharma

Reputation: 26

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:

  1. 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:

  2. 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

Upvotes: 1

Related Questions