felangel / bloc

A predictable state management library that helps implement the BLoC design pattern
https://bloclibrary.dev
MIT License
11.79k stars 3.39k forks source link

Navigation between blocs #474

Closed adithya421 closed 5 years ago

adithya421 commented 5 years ago

Hi Felagel,

Your Flutter Bloc package was awsome.

I am facing an issue while implementing the MultiBlocProviders and navigation between the blocs. Please find the below example for your reference.

I have below blocs in my application

  1. Login bloc 2.Auth bloc 3.Home Page bloc(List of students)
  2. Student Details Bloc

With reference to the flutter_firebase_todo sample application, I implemented Multi Bloc Providers

On click of selected student from List of Students(HomePage), the app should navigate to another page(Student Details)( Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) { return StudentDetailsPage(id:123); }));) in this page, I try to initiate another bloc (Student details bloc). But it's not able to initiate. Please advise. How to initiate another bloc when it's navigating from one page to another via(Navigator.push())

Looking forward to your response.

carmenkerim12 commented 5 years ago

Hey, I'm just a developer using the bloc library but I thought I would give my 2 cents to help out Felix since he helped me out a lot.

When navigating to another screen with navigator.push you want to surround your widget(screen) with a BlocProvider . With the new version of flutter_bloc 0.19.0, the BlocProvider will handle disposing of your blocs. what's new in 0.19.0.

So to make it simple,

Navigating

  Navigator.push(
    context,
    MaterialPageRoute(builder: (context) => CounterPage()),
  );

Navigating with BlocProvider

would turn into

Navigator.of(context).push(
  MaterialPageRoute<CounterPage>(
    builder: (context) {
   return BlocProvider(
         builder: (BuildContext context) => CounterBloc(),
        child: CounterPage(),
      );
    },
  ),
);

To access the bloc in the the Widget you provided it to, you would use

_counterBloc = BlocProvider.of<CounterBloc>(context)

StatefulWidget: -> Access it in the InitState StatelessWidget -> Use the same thing but access in the build method

Passing an existing bloc

When you want to pass that bloc to another screen, you would use this method as it prevents you from recreating another bloc

Providing access to a Widget with an existing Bloc

Navigator.of(context).push(
  MaterialPageRoute<CounterPage2>(
    builder: (context) {
      return BlocProvider.value(
        value: _counterBloc,
        child: CounterPage2(),
      );
    },
  ),
);

All this can be applied with a MultiBlocProvider as well.

This is all covered in his article

https://felangel.github.io/bloc/#/recipesflutterblocaccess

Cheers!

felangel commented 5 years ago

Hi @adithya421 👋 Thanks for opening an issue!

@carmenkerim12 covered everything perfectly so please let us know if you have any questions.

Closing for now and thanks @carmenkerim12 for the awesome answer. I really appreciate the help! 🙏