Flutter bloc: updating the state does not re-call BlocBuilder

4,746

The problem is here:

...
onTap: () {
...
  HomeBloc().getAllCats();
...
},
...

It should be _homeBloc.getAllCats();

Share:
4,746
Mahmoud Mabrouk
Author by

Mahmoud Mabrouk

Updated on December 13, 2022

Comments

  • Mahmoud Mabrouk
    Mahmoud Mabrouk over 1 year

    I have a page being managed using bloc

    here is the home_state.dart

    import 'package:banha/data/models/category.dart';
    import 'package:flutter/material.dart';
    
    abstract class HomeState {
      HomeState() : super();
    }
    
    class HomeInitial extends HomeState {}
    
    class UpdateCats extends HomeState {
      final List<Category> cats;
      final int rand;
      UpdateCats({@required this.cats,@required this.rand}){
        print(this.cats);
        print(this.rand);
      }
    }
    

    and the home_bloc.dart (note: the Random number is just to make sure the state is diff from the prev one)

    import 'dart:math';
    
    import 'package:banha/data/models/category.dart';
    import 'package:banha/data/network/categories.dart';
    import 'package:banha/ui/tabs/home/bloc/home_events.dart';
    import 'package:banha/ui/tabs/home/bloc/home_states.dart';
    import 'package:bloc/bloc.dart';
    
    class HomeBloc extends Bloc<HomeEvents, HomeState> {
      getAllCats() {
        dispatch(HomeGetCategories());
      }
    
      HomeBloc() : super();
    
      @override
      HomeState get initialState => HomeInitial();
    
      @override
      Stream<HomeState> mapEventToState(HomeEvents event) async* {
        if (event is HomeGetCategories) {
          yield* _getCats();
        }
      }
    
      Stream<HomeState> _getCats() async* {
        print("getting cats");
        List<Category> newCats;
        await Network_getAllCategories().then((List<Category> cats) {
          newCats = cats;
        });
        yield UpdateCats(cats: newCats, rand: Random().nextInt(21312545));
      }
    }
    

    and the page widget:

    import 'package:banha/ui/category/category.dart';
    import 'package:banha/ui/tabs/home/bloc/home_bloc.dart';
    import 'package:banha/ui/tabs/home/bloc/home_states.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter/cupertino.dart';
    import 'package:flutter_bloc/flutter_bloc.dart';
    
    class ListingsWidget extends StatefulWidget {
      @override
      _ListingsWidgetState createState() => _ListingsWidgetState();
    }
    
    class _ListingsWidgetState extends State<ListingsWidget> {
      final HomeBloc _homeBloc = HomeBloc();
    
      @override
      void initState() {
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Container(
          height: 130,
          padding: EdgeInsets.only(top: 10, bottom: 10),
          child: BlocListener(
            bloc: _homeBloc,
            listener: (context, state) {
              print(state);
            },
            child: BlocBuilder<HomeBloc, HomeState>(
              bloc: _homeBloc,
              builder: (BuildContext context,HomeState state) {
                if(state is UpdateCats){
                  print(state.cats);
                }
                return ListView(
                  scrollDirection: Axis.horizontal,
                  children: <Widget>[
                    InkWell(
                      borderRadius: BorderRadius.circular(1000),
                      onTap: () {
                        HomeBloc().getAllCats();
    //                    Navigator.push(context, CupertinoPageRoute(builder: (context) => CategoryPage()));
                      },
    ....
    

    the issue is that in the view(Widget) BlocBuilder is just being called once on initial, but when I try to test changing the state using HomeBloc().getAllCats(); and then print the new State using this code:

    if(state is UpdateCats){
                  print(state.cats);
                }
    

    nothing happens (Builder is not being called ever again), what's wrong with my code?

    • Tokenyet
      Tokenyet over 4 years
      Im not sure why, but have you tried BlocDelegate to see the state transition, that would be very helpful on debugging If you could provide the logs from this.
  • Tokenyet
    Tokenyet over 4 years
    I just found out you did a strange thing in your code. HomeBloc().getAllCats();, you use a local bloc but init a new bloc when dispatching an event. BlocProvider is not the real issue since you use local bloc.
  • Mahmoud Mabrouk
    Mahmoud Mabrouk over 4 years
    @Tokenyet Exactly