Should I use final in models with equatable and flutter_bloc to distinguish 2 states?

201 views Asked by At

I'm creating an app where you login and go to a page where you have a list of your restaurants, you have also a form where you can add a new restaurant.

This part works.

The problem is that when i click add the restaurant is added in firestore correctly, but the list doesn't refresh. I usually yield 2 states, a LoadingState and a LoadedRestaurantsListState, but with the last version of flutter_bloc this trick doesn't work, seems like just the last state yielded is received, but the previous was LoadedRestaurantsListState, so they are equals and the blocbuilder ignores the second one. So I've to use the equatable's props to distinguish the 2 states, but in the equatable documentation is written: "Note: Equatable is designed to only work with immutable objects so all member variables must be final".

So I've to make all the model's fields final, but if I do it how can i modify just one o two fields when I need it to? What is the best practice? If someone has examples, or videos, etc it would be very appreciated. Thanks in advance

Without props

FirebaseBloc.dart

 Stream<FirebaseState> mapEventToState(
    FirebaseEvent event,
  ) async* {
    print("event firebase ${event.runtimeType.toString()}");
       
    if (event is CreateRestaurantFirebaseEvent) {
      yield LoadingState();
      await _databaseService.createRestaurant(event.restaurant, event.user);
      List<Restaurant> restaurantsList = await _databaseService
          .loadRestaurantsList(event.user.restaurantsIDsList);
      yield LoadedRestaurantsListState(restaurantsList);
    }

    if (event is LoadRestaurantsListEvent) {
      List<Restaurant> restaurantsList =
          await _databaseService.loadRestaurantsList(event.restaurantsIDs);
      yield LoadedRestaurantsListState(restaurantsList);
    }

FirebaseState.dart

class LoadingState extends FirebaseState {
  @override
  List<Object> get props => [];
}

class LoadedRestaurantsListState extends FirebaseState {
  List<Restaurant> restaurantsList;

  LoadedRestaurantsListState(this.restaurantsList);

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

view.dart

class RestaurantSelectionScreen extends StatefulWidget {
  final User user;

  RestaurantSelectionScreen({
    @required this.user,
  });

  @override
  _RestaurantSelectionScreenState createState() =>
      _RestaurantSelectionScreenState();
}

class _RestaurantSelectionScreenState extends State<RestaurantSelectionScreen> {
  FirebaseBloc _firebaseBloc;

  @override
  void initState() {
    super.initState();

    _firebaseBloc = FirebaseBloc();
    _firebaseBloc.add(LoadRestaurantsListEvent(widget.user.restaurantsIDsList));
  }

  @override
  Widget build(BuildContext context) {
    return BlocProvider<FirebaseBloc>(
      create: (context) => _firebaseBloc,
      child: Scaffold(
        body: SingleChildScrollView(
          child: Center(
            child: BlocBuilder(
              cubit: _firebaseBloc,
              builder: (context, state) {
                print("state ${state.runtimeType.toString()}");

                if (state is InitialFirebaseState) {
                  return CircularProgressIndicator();
                } else if (state is LoadedRestaurantsListState) {
                  return buildUI(state);
                } else if (state is LoadingState) {
                  return CircularProgressIndicator();
                } else {
                  return _CreateRestaurantFormWidget(widget.user);
                }
              },
            ),
          ),
        ),
      ),
    );
  }
0

There are 0 answers