简体   繁体   中英

Flutter bloc fill initial state with data

I have a question about bloc correct code placement so to say. So as bloc stands for business logic component I've moved business logic (like processing data methods) inside class. So now there are 2 methods one for getting and second for saving data. Next, I have my component which within AddInitial should show loading, then fire bloc saying "hey, I need data here". Is it correct or it's antipattern? Code looks like this.

BlocBuilder<AddBloc, AddState>(
  buildWhen: (previous, current) {
    // code is ommited
  },
  builder: (context, state) {
    if (state is ExpensesLoaded || state is CategoryChanged) {
      // code is ommited
    } else if (state is ExpensesLoading) {
      return getProgressSpinner();
    } else if (state is AddInitial) {
      // is it ok? If it's antipattern please give an advise how to do it correctly
      context.bloc<AddBloc>().add(CategoryChange([category]));
      return getProgressSpinner();
    } else {
      print('Bloc Loaded. Nothing to show inside Month Expenses...');
      return Container();
    }
  }

Question about context.bloc<AddBloc>().add(CategoryChange([category])); . Is it antipattern? How this should be done?

By the way when it looks like this. Next time when I add CategoryChange event to bloc (which will yields CategoryChanged state) builder from above doesn't react for some reason...

Thanks!

I'm using Flutter 1.22.3, flutter_bloc: 6.1.0

How this should be done?

When you know your initial state of your Bloc when you create it (lets say a static list with the first entry pre-selected by default) then you can use the Bloc constructor that takes that initial state as a parameter.

If you don't know what the correct initial state is, because it is dynamic (lets say a list of locations loaded from a service based on GPS that the user has to agree to get by button click because it costs money) then it's perfectly fine to have an "empty" or "uninitialized" or "waitingForUserInteraction" state. After all, that is the state of your program then.

By the way when it looks like this. Next time when I add CategoryChange event to bloc (which will yields CategoryChanged state) builder from above doesn't react for some reason

The bloc finds out whether to send out a new state change by comparing the old and new state. If you want to modify the default behavior, you can make sure the two states compare as equal (or not). The easiest way to do that is derive your states from Equatable in the package equatable like this:

@immutable
abstract class SomeState extends Equatable {
  final String importantChange;
  final String unimportantChange;

  const SomeState(this.importantChange, this.unimportantChange);

  @override
  List<Object> get props => [importantChange]; 
}

Only listing one field in the "props" list means only this is compared when comparing for equality. If importantChange is equal, the states are considered equal (and will not be emitted from the Bloc). Two states having the same importantChange but different unimportantChange are considered the same.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM