Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] Bloc observer not working #3022

Closed
linxkaa opened this issue Dec 1, 2021 · 23 comments
Closed

[Question] Bloc observer not working #3022

linxkaa opened this issue Dec 1, 2021 · 23 comments
Assignees
Labels
pkg:bloc This issue is related to the bloc package question Further information is requested

Comments

@linxkaa
Copy link

linxkaa commented Dec 1, 2021

Hi @felangel. I tried to implement of blocObserver after the migration.

this is what my blocObserver looks like.

// ignore_for_file: avoid_print

import 'package:bloc/bloc.dart';

class SimpleBlocObserver extends BlocObserver {
  @override
  void onCreate(BlocBase bloc) {
    super.onCreate(bloc);
    print('onCreate Bloc-- ${bloc.runtimeType}');
  }

  @override
  void onChange(BlocBase bloc, Change change) {
    super.onChange(bloc, change);
    print('onChange Bloc type-- ${bloc.runtimeType}');
    print('onChange Bloc CurrentState-- ${change.currentState}');
    print('onChange Bloc NextState-- ${change.nextState}');
  }

  @override
  void onError(BlocBase bloc, Object error, StackTrace stackTrace) {
    print('onError Bloc-- ${bloc.runtimeType}, $error');
    super.onError(bloc, error, stackTrace);
  }

  @override
  void onClose(BlocBase bloc) {
    super.onClose(bloc);
    print('onClose Bloc-- ${bloc.runtimeType}');
  }
}

and this is my main.dart file

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  BlocOverrides.runZoned(
    () {},
    blocObserver: SimpleBlocObserver(),
  );
  return  runApp(Env.dev));
}

and it didn't print anything. Previously i do this with Bloc.observer = SimpleBlocObserver() and my bloc will automatically printed in console. But now it doesn't.

if i put this this way:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
    BlocOverrides.runZoned(
    () {
      cubitMain();
    },
    blocObserver: SimpleBlocObserver(),
  );
  return runApp(Env.dev);
}

with the cubitMain() codes like this:

void cubitMain() {
  print('----------CUBIT----------');
  final bloc = getIt<ShareImageBloc>();
  print(bloc.state); 
  cubit.close();
}

it will trigger only in the first time application is running, but not when the state is changed. While the previous version is whenever i create a bloc and trigger an event, the bloc observer should always be triggered.

Is there anything wrong with my code? Thank you in advance!

@linxkaa linxkaa added the bug Something isn't working label Dec 1, 2021
@linxkaa linxkaa changed the title [Question] [Question] Bloc observer not working Dec 1, 2021
@felangel
Copy link
Owner

felangel commented Dec 1, 2021

Hi @linxkaa 👋
Thanks for opening an issue!

Can you remove the WidgetsFlutterBinding.ensureInitialized and verify if that solves the problem? If you aren’t accessing the underlying platforms before runApp then you should remove it. If you need access to the underlying platforms then you should use https://pub.dev/packages/flutter_services_binding.

You can read more about this at flutter/flutter#94123.

Let me know if that helps and sorry for any inconvenience!

@felangel felangel self-assigned this Dec 1, 2021
@felangel felangel added pkg:bloc This issue is related to the bloc package question Further information is requested waiting for response Waiting for follow up labels Dec 1, 2021
@linxkaa
Copy link
Author

linxkaa commented Dec 1, 2021

Hi @felangel thank you for responding!

I already changed to this

void main() {
  BlocOverrides.runZoned(
    () {},
    blocObserver: SimpleBlocObserver(),
  );
  return runTokocuanApp(TokocuanEnv.dev);
}

fyi the runApp i access in the code before isnt the actually runApp, i called other class like this

void runTokocuanApp(String env) async {
  WidgetsFlutterBinding.ensureInitialized();
  configureInjection(env);
  await SystemChrome.setPreferredOrientations(
    [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown],
  );
  return runApp(const TokocuanApp());
}

Things i tried: I already tried moving the BlocOverrides to runTokocuanApp and removes all the widgetsFlutterBinding, but nothing happen.

And i cant remove the WidgetsFlutterBinding.ensureInitialized() on the runTokocuanApp because it called this,

  await SystemChrome.setPreferredOrientations(
    [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown],
  );

if i remove it, it will throw this error
Screen Shot 2021-12-01 at 21 51 45

@felangel
Copy link
Owner

felangel commented Dec 1, 2021

void main() {
  BlocOverrides.runZoned(
    () => runTokocuanApp(…),
    blocObserver: SimpleBlocObserver(),
  );
}

You need to move the code within the body of the zone.

@linxkaa
Copy link
Author

linxkaa commented Dec 1, 2021

Ohh i see! Thank you very much! Its working now!

@linxkaa linxkaa closed this as completed Dec 1, 2021
@felangel felangel removed bug Something isn't working waiting for response Waiting for follow up labels Dec 1, 2021
@kashlo
Copy link

kashlo commented Dec 29, 2021

Ive tried the above solution, but observer still doesn't work, no logs are showing

@felangel
Copy link
Owner

Ive tried the above solution, but observer still doesn't work, no logs are showing

Can you provide a link to a minimal reproduction sample? Thanks!

@kashlo
Copy link

kashlo commented Dec 29, 2021

Future<void> main() async {
  await setUp();
  BlocOverrides.runZoned(
    () {
      return runApp(
        BlocProvider<AuthenticationBloc>(
          create: (_) => GetIt.instance<AuthenticationBloc>(),
          child: MyApp(),
        )
      );
    },
    blocObserver: SimpleBlocObserver(),
  );
}

Future<void> setUp() async {
  WidgetsFlutterBinding.ensureInitialized();

  GetIt.instance.registerSingleton<AuthenticationBloc>(AuthenticationBloc());
  GetIt.instance<AuthenticationBloc>().add(AppStarted());
}

@felangel
Copy link
Owner

WidgetsFlutterBinding.ensureInitialized();

This is because you're using WidgetsFlutterBinding.ensureInitialized();.

If you replace it with FlutterServicesBinding.ensureInitialized(); from package:flutter_services_binding it should resolve the issue.

You can see flutter/flutter#94123 for more info 👍

@kashlo
Copy link

kashlo commented Dec 29, 2021

added plugin, changed to FlutterServicesBinding.ensureInitialized();
still no logs from the observer :/

@felangel
Copy link
Owner

added plugin, changed to FlutterServicesBinding.ensureInitialized();
still no logs from the observer :/

Can you also move the setup into the runZoned body?

Future<void> main() async {
  await BlocOverrides.runZoned(
    () async {
      await setUp();
      return runApp(
        BlocProvider<AuthenticationBloc>(
          create: (_) => GetIt.instance<AuthenticationBloc>(),
          child: MyApp(),
        )
      );
    },
    blocObserver: SimpleBlocObserver(),
  );
}

@kashlo
Copy link

kashlo commented Dec 29, 2021

@felangel Now logs are visible, thanks a lot :)

@noor848
Copy link

noor848 commented Jan 13, 2022

hello i put it in this way and it doesnt work

void main() {

////FlutterServicesBinding.ensureInitialized();
BlocOverrides.runZoned(
() {
runApp(const MyApp());
},
blocObserver: MyBlocObserver(),
);

}

@felangel
Copy link
Owner

hello i put it in this way and it doesnt work

void main() {

////FlutterServicesBinding.ensureInitialized(); BlocOverrides.runZoned( () { runApp(const MyApp()); }, blocObserver: MyBlocObserver(), );

}

Can you share your full main.dart?

@noor848
Copy link

noor848 commented Jan 13, 2022

this is my main
/////////////

import 'package:bloc/bloc.dart';
import 'package:bma/counter.dart';
import 'package:bma/module/counter/cubit.dart';
import 'package:bma/module/counter/statecounter.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_services_binding/flutter_services_binding.dart';
import 'BMI_cal.dart';
import 'login_page.dart';
import 'module/square_rotate/square.dart';
import 'shared/blocobserver.dart';

void main() {

FlutterServicesBinding.ensureInitialized();
BlocOverrides.runZoned(
() {
runApp(const MyApp());
},
blocObserver: MyBlocObserver(),
);

}

class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);

@OverRide
Widget build(BuildContext context) {
return MaterialApp(

  debugShowCheckedModeBanner: false,
  home: Counter(),



);

}
}

@noor848
Copy link

noor848 commented Jan 13, 2022

i tried your both solution adding this FlutterServicesBinding.ensureInitialized(); and without and no result show

@felangel
Copy link
Owner

i tried your both solution adding this FlutterServicesBinding.ensureInitialized(); and without and no result show

Do you have a link to a minimal reproduction sample?

@noor848
Copy link

noor848 commented Jan 13, 2022

image
image

@noor848
Copy link

noor848 commented Jan 13, 2022

@felangel
Copy link
Owner

and this my simple work link https://github.com/noor848/Flutter_project/tree/counter/lib/module/counter

I'm not able to reproduce the issue. You can refer to the official DartPad and see the BlocObserver logs in the console:

Screen Shot 2022-01-13 at 12 52 37 PM

@noor848
Copy link

noor848 commented Jan 13, 2022

thank you it works actually i guess the problem was the ide is slow

@omarmorsi99
Copy link

hello this is my main with no log observer if you can help

Future main() async{
BlocOverrides.runZoned(
() => const MyApp(),
blocObserver: AppBlocObserver(),
);

WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);

}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@OverRide
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(create: (context) => AppCubit()..getUserData()..getPosts()..getUsers()),
],
child: BlocConsumer<AppCubit,AppStates>(
listener: (context, state) {},
builder: (context,state) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Register_Screen(),
);
}),
);
}
}

@felangel
Copy link
Owner

felangel commented Mar 20, 2022

@omarmorsi99 you need to move your WidgetsFlutterBinding and Firebase calls within the runZoned callback like:

void main() {
  BlocOverrides.runZoned(
    () async {
      WidgetsFlutterBinding.ensureInitialized();
      await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
      runApp(const MyApp());
    },
    blocObserver: AppBlocObserver(),
  );
}

Hope that helps 👍

@Jashemaits
Copy link

Hello! onError is not getting called from blocObserver for blocs of nested page. but it is getting called on my tab bar but if i navigate to a different page and that page has a blocProvider that is not printing any error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg:bloc This issue is related to the bloc package question Further information is requested
Projects
None yet
Development

No branches or pull requests

6 participants