Bloc: Data received in state is not available immediately

Created on 29 May 2020  路  7Comments  路  Source: felangel/bloc

Hi, I'm experimenting a weird behaviour when listening to a state.
On receiving UserLocation state I print the state property and use it to send two events GetCityUser and GetCityDb that make a request to an API. State print shows wrong value and GetCityUser fails as it doesn't have a value in it, but GetCityDb does't fail.

I then tried using a Timer waiting 50 ms to send both events and they both worked fine..
So I made another test.. sending the events multiple times, and only the first always fails as it's missing the correct state value..

This happens only on the web app..on iPad runs correctly.. Any idea of why State value is not readily available when receiving the state?
I'm using flutter_bloc: ^3.2.0.
Thank you ver much.
This is the code:


class _BookingScreenState extends State<BookingScreen> {
  FixitUser user;
  LatLng userLocation = LatLng(0, 0);
  String isoLocation;
  String cityUser;
  String regionUser;
  String countryUser;
  String cityDb;
  String regionDb;
  String countryDb;
  @override
  Widget build(BuildContext context) {
    return MultiBlocProvider(
      providers: [
        BlocProvider<LocationBloc>(
          lazy: false,
          create: (context) => LocationBloc()..add(GetLocation()),
        ),
        BlocProvider<GeoBloc>(
          lazy: false,
          create: (context) => GeoBloc(),
        ),
      ],
      child: BlocBuilder<LocationBloc, LocationState>(
        builder: (context, state) => MultiBlocListener(
          listeners: [
            BlocListener<LocationBloc, LocationState>(
              listener: (BuildContext context, LocationState state) {
                if (state is UserLocation) {
                  setState(() {
                    print(
                        'Test 0 LocationBlocListener state.location is ${state.location.latitude},${state.location.longitude}');
                    // prints LocationBlocListener state.location is 0,0 ???
                    userLocation = state.location;

                    //Test 1 : Assign state value to variable and use it to send events
                    print('Test 1');
                    print(
                        'Test 1 LocationBlocListener state.location is ${state.location.latitude},${state.location.longitude}');
                    // GetCityUser gets called with state.location is 0,0 and fails..
                    BlocProvider.of<GeoBloc>(context)
                        .add(GetCityUser(userLocation));

                    BlocProvider.of<GeoBloc>(context)
                        .add(GetCityDb(userLocation));

                    // Test 2 : using state value directly
                    print('Test 2');
                    print(
                        'Test 2 LocationBlocListener state.location is ${state.location.latitude},${state.location.longitude}');
                    // GetCityUser gets called with state.location is 0,0 and fails..
                    BlocProvider.of<GeoBloc>(context)
                        .add(GetCityUser(state.location));

                    // GetCityDb gets called with correct state.location
                    BlocProvider.of<GeoBloc>(context)
                        .add(GetCityDb(state.location));

                    // Test 3 : Adding a Timer makes both events to be called with correct  coordinates.
                    print('Test 3');
                    print(
                        'Test 2 LocationBlocListener state.location is ${state.location.latitude},${state.location.longitude}');
                    Timer(Duration(milliseconds: 50), () {
                      print(
                          'LocationBlocListener sent GetCityUser and GetCityDb events with Timer..');
                      BlocProvider.of<GeoBloc>(context)
                          .add(GetCityUser(userLocation));
                      BlocProvider.of<GeoBloc>(context)
                          .add(GetCityDb(userLocation));
                    });
                  });
                }
              },
            ),
            BlocListener<GeoBloc, GeoState>(
                listener: (BuildContext context, GeoState state) {
              if (state is CityUser) {
                print('CityUser state');
                setState(() {
                  cityUser = (state).city;
                  regionUser = (state).region;
                  countryUser = (state).country;
                });
              }

              if (state is CityDb) {
                print('CityDb state');
                setState(() {
                  cityDb = (state).city;
                  regionDb = (state).region;
                  countryDb = (state).country;
                });
              }
            }),
          ],
          child: Scaffold(
            body: Container(
...

and the prints from Chrome console:


Test 0 LocationBlocListener state.location is 0,0
js_primitives.dart:49 Test 1
js_primitives.dart:49 Test 1 LocationBlocListener state.location is 0,0
js_primitives.dart:49 Test 2
js_primitives.dart:49 Test 2 LocationBlocListener state.location is 0,0
js_primitives.dart:49 Test 3
js_primitives.dart:49 Test 2 LocationBlocListener state.location is 0,0
js_primitives.dart:49 GetCityUser event received coordinated LatLng(latitude:0.0, longitude:0.0)
js_primitives.dart:49 LocationBlocListener sent GetCityUser and GetCityDb events with Timer..
html_dart2js.dart:17796 GET http://geodb-free-service.wirefreethought.com/v1/geo/cities?location=00&radius=15&minPopulation=100000 400 (Bad Request)
e_ @ main.dart.js:24566
adr @ main.dart.js:2566
(anonymous) @ browser_client.dart:87
(anonymous) @ main.dart.js:2646
$2 @ main.dart.js:21305
$1 @ async_patch.dart:283
w7 @ main.dart.js:22439
kP @ main.dart.js:22441
$0 @ future_impl.dart:139
lj @ future_impl.dart:706
nD @ future_impl.dart:524
$0 @ main.dart.js:21661
ahT @ schedule_microtask.dart:43
ai5 @ schedule_microtask.dart:47
$1 @ async_patch.dart:51
ajr @ js_helper.dart:2026
(anonymous) @ js_helper.dart:2049
childList (async)
$1 @ async_patch.dart:64
aaE @ schedule_microtask.dart:70
a1S @ zone.dart:1187
e2 @ zone.dart:294
nd @ stream_impl.dart:663
h6 @ stream_impl.dart:324
fs @ broadcast_stream_controller.dart:416
B @ broadcast_stream_controller.dart:252
B @ subject.dart:135
B @ subject.dart:161
$1 @ booking_screen.dart:39
gk @ inherited_provider.dart:353
bx @ inherited_provider.dart:296
ir @ framework.dart:4217
ir @ inherited_provider.dart:194
mS @ framework.dart:3947
rv @ main.dart.js:43722
cn @ framework.dart:4201
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
cn @ framework.dart:4201
cn @ nested.dart:223
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
cn @ framework.dart:4201
cn @ nested.dart:223
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
cn @ framework.dart:4201
cn @ nested.dart:188
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
cn @ framework.dart:4201
cn @ nested.dart:223
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
cn @ framework.dart:4201
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
rv @ framework.dart:4381
cn @ framework.dart:4201
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
cn @ framework.dart:4201
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
cn @ framework.dart:4201
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
cn @ framework.dart:4201
cn @ main.dart.js:43797
v4 @ framework.dart:3194
cn @ framework.dart:5550
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
rv @ framework.dart:4381
cn @ framework.dart:4201
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
cn @ framework.dart:4201
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
rv @ framework.dart:4381
cn @ framework.dart:4201
v4 @ framework.dart:3194
cp @ framework.dart:2983
cn @ framework.dart:5445
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
cn @ framework.dart:4201
v4 @ framework.dart:3194
cp @ framework.dart:2983
cn @ framework.dart:5445
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
rv @ framework.dart:4381
cn @ framework.dart:4201
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
rv @ framework.dart:4381
cn @ framework.dart:4201
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
cn @ framework.dart:4201
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
cn @ framework.dart:4201
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
rv @ framework.dart:4381
cn @ framework.dart:4201
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
rv @ framework.dart:4381
cn @ framework.dart:4201
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
ir @ inherited_provider.dart:194
mS @ framework.dart:3947
rv @ main.dart.js:43722
cn @ framework.dart:4201
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
cn @ framework.dart:4201
cn @ nested.dart:223
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
cn @ framework.dart:4201
cn @ nested.dart:223
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
cn @ framework.dart:4201
cn @ nested.dart:188
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
cn @ framework.dart:4201
cn @ nested.dart:223
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
rv @ main.dart.js:43722
cn @ framework.dart:4201
v4 @ framework.dart:3194
cp @ framework.dart:2983
ir @ framework.dart:4226
mS @ framework.dart:3947
oJ @ framework.dart:2426
RQ @ main.dart.js:43553
uB @ binding.dart:772
requestAnimationFrame (async)
Pz @ main.dart.js:25044
$0 @ html_dart2js.dart:30562
hD @ window.dart:735
hD @ binding.dart:784
uF @ main.dart.js:39370
LG @ main.dart.js:41934
eval @ VM6494:3
wV @ framework.dart:2316
eJ @ framework.dart:3915
at @ framework.dart:1168
$1 @ bloc_builder.dart:174
w8 @ zone.dart:1313
mX @ main.dart.js:22423
fs @ stream_impl.dart:338
dh @ stream_impl.dart:264
dh @ stream_pipe.dart:134
nT @ stream_pipe.dart:417
LO @ main.dart.js:22214
eval @ VM6563:3
w8 @ zone.dart:1313
mX @ main.dart.js:22423
fs @ stream_impl.dart:338
dh @ stream_impl.dart:264
fs @ main.dart.js:21931
dh @ stream_controller.dart:641
B @ stream_controller.dart:588
eval @ VM6569:3
w8 @ zone.dart:1313
mX @ main.dart.js:22423
fs @ stream_impl.dart:338
vT @ main.dart.js:22122
D8 @ stream_impl.dart:709
$0 @ stream_impl.dart:669
ahT @ schedule_microtask.dart:43
ai5 @ schedule_microtask.dart:47
$1 @ async_patch.dart:51
ajr @ js_helper.dart:2026
(anonymous) @ js_helper.dart:2049
childList (async)
$1 @ async_patch.dart:64
aaE @ schedule_microtask.dart:70
a1S @ zone.dart:1187
hE @ main.dart.js:22452
bK @ future_impl.dart:553
bY @ future_impl.dart:42
$1 @ js_util_dart2js.dart:147
ajr @ js_helper.dart:2026
(anonymous) @ js_helper.dart:2049
e.g @ firebase-auth.js:1
Pe @ firebase-auth.js:1
De @ firebase-auth.js:1
t.ec @ firebase-auth.js:1
pe @ firebase-auth.js:1
Promise.then (async)
re @ firebase-auth.js:1
le @ firebase-auth.js:1
Re @ firebase-auth.js:1
_e @ firebase-auth.js:1
(anonymous) @ firebase-auth.js:1
t.onsuccess @ firebase-auth.js:1
IndexedDB (async)
(anonymous) @ firebase-auth.js:1
e.g @ firebase-auth.js:1
Pe @ firebase-auth.js:1
De @ firebase-auth.js:1
t.ec @ firebase-auth.js:1
pe @ firebase-auth.js:1
Promise.then (async)
re @ firebase-auth.js:1
le @ firebase-auth.js:1
Re @ firebase-auth.js:1
_e @ firebase-auth.js:1
(anonymous) @ firebase-auth.js:1
t.onsuccess @ firebase-auth.js:1
IndexedDB (async)
(anonymous) @ firebase-auth.js:1
e.g @ firebase-auth.js:1
Pe @ firebase-auth.js:1
De @ firebase-auth.js:1
t.ec @ firebase-auth.js:1
pe @ firebase-auth.js:1
Promise.then (async)
re @ firebase-auth.js:1
le @ firebase-auth.js:1
Re @ firebase-auth.js:1
_e @ firebase-auth.js:1
(anonymous) @ firebase-auth.js:1
t.onsuccess @ firebase-auth.js:1
IndexedDB (async)
(anonymous) @ firebase-auth.js:1
e.g @ firebase-auth.js:1
Pe @ firebase-auth.js:1
De @ firebase-auth.js:1
t.ec @ firebase-auth.js:1
pe @ firebase-auth.js:1
Promise.then (async)
re @ firebase-auth.js:1
le @ firebase-auth.js:1
Re @ firebase-auth.js:1
_e @ firebase-auth.js:1
(anonymous) @ firebase-auth.js:1
(anonymous) @ firebase-auth.js:1
(anonymous) @ firebase-auth.js:1
gn @ firebase-auth.js:1
pn.dispatchEvent @ firebase-auth.js:1
ya @ firebase-auth.js:1
t.Hc @ firebase-auth.js:1
t.Sb @ firebase-auth.js:1
XMLHttpRequest.send (async)
va @ firebase-auth.js:1
Ha.w @ firebase-auth.js:1
$a @ firebase-auth.js:1
(anonymous) @ firebase-auth.js:1
ve @ firebase-auth.js:1
ts @ firebase-auth.js:1
(anonymous) @ firebase-auth.js:1
e.g @ firebase-auth.js:1
Pe @ firebase-auth.js:1
De @ firebase-auth.js:1
t.ec @ firebase-auth.js:1
pe @ firebase-auth.js:1
Promise.then (async)
re @ firebase-auth.js:1
le @ firebase-auth.js:1
Re @ firebase-auth.js:1
_e @ firebase-auth.js:1
(anonymous) @ firebase-auth.js:1
(anonymous) @ firebase-auth.js:1
(anonymous) @ firebase-auth.js:1
gn @ firebase-auth.js:1
pn.dispatchEvent @ firebase-auth.js:1
ya @ firebase-auth.js:1
t.Hc @ firebase-auth.js:1
t.Sb @ firebase-auth.js:1
XMLHttpRequest.send (async)
va @ firebase-auth.js:1
Ha.w @ firebase-auth.js:1
$a @ firebase-auth.js:1
(anonymous) @ firebase-auth.js:1
ve @ firebase-auth.js:1
ts @ firebase-auth.js:1
(anonymous) @ firebase-auth.js:1
e.g @ firebase-auth.js:1
Pe @ firebase-auth.js:1
De @ firebase-auth.js:1
t.ec @ firebase-auth.js:1
pe @ firebase-auth.js:1
Promise.then (async)
re @ firebase-auth.js:1
le @ firebase-auth.js:1
Re @ firebase-auth.js:1
Se @ firebase-auth.js:1
Ne @ firebase-auth.js:1
ve.then @ firebase-auth.js:1
t.Ya @ firebase-auth.js:1
i @ firebase-auth.js:1
qp @ main.dart.js:20072
adu @ main.dart.js:2569
qp @ main.dart.js:26922
(anonymous) @ platform_user_repository_web.dart:94
(anonymous) @ main.dart.js:2646
$2 @ main.dart.js:21305
$1 @ async_patch.dart:283
w7 @ main.dart.js:22439
kP @ main.dart.js:22441
$0 @ future_impl.dart:139
lj @ future_impl.dart:706
$0 @ main.dart.js:21635
ahT @ schedule_microtask.dart:43
ai5 @ schedule_microtask.dart:47
$1 @ async_patch.dart:51
ajr @ js_helper.dart:2026
(anonymous) @ js_helper.dart:2049
childList (async)
$1 @ async_patch.dart:64
aaE @ schedule_microtask.dart:70
a1S @ zone.dart:1187
hE @ main.dart.js:22452
bK @ future_impl.dart:553
bY @ future_impl.dart:42
$1 @ js_util_dart2js.dart:147
ajr @ js_helper.dart:2026
(anonymous) @ js_helper.dart:2049
e.Sr @ cb=gapi.loaded_0:205
Ok @ cb=gapi.loaded_0:208
Jk @ cb=gapi.loaded_0:208
_.uk.zU @ cb=gapi.loaded_0:208
tk @ cb=gapi.loaded_0:200
Promise.then (async)
ok @ cb=gapi.loaded_0:200
_.sk @ cb=gapi.loaded_0:200
Kk @ cb=gapi.loaded_0:207
_.uk.rh @ cb=gapi.loaded_0:206
(anonymous) @ cb=gapi.loaded_0:201
tokenReady @ cb=gapi.loaded_0:350
a.Jw.<computed> @ cb=gapi.loaded_0:350
Ax.We @ cb=gapi.loaded_0:349
(anonymous) @ cb=gapi.loaded_0:348
av.dispatchEvent @ cb=gapi.loaded_0:260
(anonymous) @ cb=gapi.loaded_0:299
_.h.W_ @ cb=gapi.loaded_0:282
(anonymous) @ cb=gapi.loaded_0:284
Show 225 more frames
js_primitives.dart:49 getCityUser() Request failed with status: 400.
js_primitives.dart:49 GetCitydb event received coordinated LatLng(latitude:44.515578, longitude:11.336774)
js_primitives.dart:49 GetCityUser event received coordinated LatLng(latitude:44.515578, longitude:11.336774)
js_primitives.dart:49 GetCitydb event received coordinated LatLng(latitude:44.515578, longitude:11.336774)
js_primitives.dart:49 GetCityUser event received coordinated LatLng(latitude:44.515578, longitude:11.336774)
js_primitives.dart:49 GetCitydb event received coordinated LatLng(latitude:44.515578, longitude:11.336774)
js_primitives.dart:49 CityDb state
js_primitives.dart:49 CityUser state
js_primitives.dart:49 CityDb state
js_primitives.dart:49 CityUser state
js_primitives.dart:49 CityDb state
question

Most helpful comment

Thank you so much. You're always super kind. Cheers.

All 7 comments

Hi @vinnytwice 馃憢
Thanks for opening an issue!

Are you able to share a link to a sample app which reproduces the issue? Also, I noticed you're running on web. Can you confirm the problem is still occurring in a release build? Thanks 馃憤

@felangel Hi Felix and thanks for answering this quick, this is just a sample app but in my main app I use values coming back from sending this two events to build new screens so sorting this out is vital. I do confirm that I'm testing it with a release run (lesson learned not too long ago .. :) Here is the sample app the problem is in booking_screen.
https://github.com/vinnytwice/firebase_bloc_web_stub
You just need to add the GoogleService_Info.plist as usual, but for web put you Firebase keys in firebase_singleton and only your google client id in the index.html file.
Thank you so much for the help

@vinnytwice would it be possible to provide a sample app that is simple and doesn't require firebase to run? It would make it easier for me to run locally, thanks! 馃檹

@felangel Done it. now it does't require firebase as I jumped the whole login/authentication. I tried and the error is still there, so you can check it by launching it with flutter run -d chrome --release --web-hostname localhost --web-port 5000..dough port now doesn't matter ..
thanks again

@vinnytwice I opened a pull request to address the problem. The issue was not related to bloc and was just due to incorrect use of futures.

Hope that helps 馃憤

Thank you so much. You're always super kind. Cheers.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rsnider19 picture rsnider19  路  3Comments

MahdiPishguy picture MahdiPishguy  路  3Comments

tigranhov picture tigranhov  路  3Comments

clicksocial picture clicksocial  路  3Comments

abinvp picture abinvp  路  3Comments