I'm actually facing 2 issues:
1) When I create a bloc, I have initial state with empty settings, but at the time the bloc is actually used, I already have the settings initialized, I would like to have dynamic initial state, so by the time a widget subscribes to the bloc, it receives the updated initialState, not the one, used when the bloc was created.
2) When I update settings, I need to yield the same state with different props, but the BlocBuilder won't rebuild, even if condition always returns true.
Here's some code:
import 'dart:async';
import 'package:aurora_mail/modules/settings/blocs/sync_settings/sync_settings_methods.dart';
import 'package:aurora_mail/modules/settings/models/sync_duration.dart';
import 'package:bloc/bloc.dart';
import './bloc.dart';
class SyncSettingsBloc extends Bloc<SyncSettingsEvent, SyncSettingsState> {
SyncFreq syncDuration;
final _methods = new SyncSettingsMethods();
SyncSettingsState _currentState = InitialSyncSettingsState(300);
@override
SyncSettingsState get initialState => _currentState;
@override
Stream<SyncSettingsState> mapEventToState(
SyncSettingsEvent event,
) async* {
if (event is InitSyncSettings) yield* _initSyncSettings(event);
if (event is SetFrequency) yield* _setFrequency(event);
}
Stream<SyncSettingsState> _initSyncSettings(InitSyncSettings event) async* {
_currentState = InitialSyncSettingsState(event.user.syncFreqInSeconds);
print("VO: freqInSeconds: ${event.user.syncFreqInSeconds}");
yield InitialSyncSettingsState(event.user.syncFreqInSeconds);
}
Stream<SyncSettingsState> _setFrequency(SetFrequency event) async* {
_methods.setFrequency(event.freq);
final freqInSeconds = SyncFreq.freqToDuration(event.freq).inSeconds;
print("VO: freqInSeconds: ${freqInSeconds}");
_currentState = InitialSyncSettingsState(freqInSeconds);
yield InitialSyncSettingsState(freqInSeconds);
}
}
Hi @VadimOsovsky 馃憢
Thanks for opening an issue!
If the process of initializing the settings is asynchronous then you must start with some initial state and then load the settings via an event and update the state accordingly. You can make this process happen earlier rather than later so a user doesn鈥檛 have to wait by moving the bloc up in the widget tree and adding the initialization event as soon as possible.
If you鈥檙e using Equatable you must pass all props to the equatable class. Please make sure you understand Equatable before using it because it鈥檚 an optimization which is not always necessary and can lead to undesired behavior when not implemented correctly. Please provide your state class implementation if you are still having trouble.
Hope that helps 馃憤
Edit: On a side note you don鈥檛 need to keep track of the blocs current state manually. You can get the blocs current state at any point in time using the state property.
Can I make it work like a Behaviour Subject, so when a new bloc builder/listener subscribes to it, it gets the latest value?
@VadimOsovsky that's how it currently works. Once a new BlocBuilder is created it will automatically get the latest bloc state. BlocListener only reacts to state changes so it will get updates on every state change. You can also access the latest bloc state via the state property
BlocProvider.of<MyBloc>(context).state; // latest state
Please refer to the documentation for more details.
@felangel sorry, my mistake, I missed one param in the props getter so it caused both of the issues, my mistake. Thanks for the info though, it was very useful, and sorry for disturbing, the issues are closed
Most helpful comment
@felangel sorry, my mistake, I missed one param in the props getter so it caused both of the issues, my mistake. Thanks for the info though, it was very useful, and sorry for disturbing, the issues are closed