Bloc: Bloc not found in context when navigating back from Custom PageRouteBuilder

Created on 18 Oct 2019  ยท  2Comments  ยท  Source: felangel/bloc

Within my main function there is LoginPage with LoginBloc provider (registerBloc not used anywhere, and also tried without it)

if (state is Unauthenticated) {
  return MultiBlocProvider(providers: [
    BlocProvider<LoginBloc>(
        builder: (BuildContext context) => LoginBloc(
              userRepository: _userRepository,
              authenticationBloc: _authenticationBloc,
            )),
    BlocProvider<RegisterBloc>(
        builder: (BuildContext context) => RegisterBloc(
              userRepository: _userRepository,
            ))
  ], child: LoginPage());
}

inside LoginPage there is

onPressed: () {
  Navigator.push(
    context,
    EnterExitRoute(

        exitPage: this,
            enterPage:RegistrationNameCompany()),
  );
}
import 'package:flutter/material.dart';

class EnterExitRoute extends PageRouteBuilder {
  final Widget enterPage;
  final Widget exitPage;
  EnterExitRoute({this.exitPage, this.enterPage})
      : super(
          pageBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
          ) =>
              enterPage,
          transitionsBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
            Widget child,
          ) =>
              Stack(
                children: <Widget>[
                  SlideTransition(
                    position: new Tween<Offset>(
                      begin: const Offset(0.0, 0.0),
                      end: const Offset(-1.0, 0.0),
                    ).animate(animation),
                    child: exitPage,
                  ),
                  SlideTransition(
                    position: new Tween<Offset>(
                      begin: const Offset(1.0, 0.0),
                      end: Offset.zero,
                    ).animate(animation),
                    child: enterPage,
                  )
                ],
              ),
        );
}

Page that is being entered is plain scaffold.

The problem occurs for the initial LoginPage when navigating, but visible when returning back from RegistrationNameCompany(). The very last line in the error is added when navigating back.

โ•โ•โ•โ•โ•โ•โ•โ• Exception caught by widgets library โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
The following assertion was thrown building MediaQuery(MediaQueryData(size: Size(411.4, 797.7), devicePixelRatio: 3.5, textScaleFactor: 1.0, platformBrightness: Brightness.light, padding: EdgeInsets(0.0, 24.0, 0.0, 0.0), viewPadding: EdgeInsets(0.0, 24.0, 0.0, 0.0), viewInsets: EdgeInsets.zero, physicalDepth: 1.7976931348623157e+308, alwaysUse24HourFormat: false, accessibleNavigation: false, disableAnimations: false, invertColors: false, boldText: false)):
        BlocProvider.of() called with a context that does not contain a Bloc of type LoginBloc.

        No ancestor could be found starting from the context that was passed to BlocProvider.of<LoginBloc>().

        This can happen if:
        1. The context you used comes from a widget above the BlocProvider.
        2. You used MultiBlocProvider and didn't explicity provide the BlocProvider types.

        Good: BlocProvider<LoginBloc>(builder: (context) => LoginBloc())
        Bad: BlocProvider(builder: (context) => LoginBloc()).

        The context used was: BlocListener<LoginBloc, LoginState>(dirty, state: _BlocListenerBaseState<LoginBloc, LoginState>#40dee(lifecycle state: created))

User-created ancestor of the error-causing widget was
    Scaffold 
lib/โ€ฆ/authentication/login.dart:142
When the exception was thrown, this was the stack
#0      BlocProvider.of 
package:flutter_bloc/src/bloc_provider.dart:80
#1      _BlocListenerBaseState.initState 
package:flutter_bloc/src/bloc_listener.dart:153
#2      StatefulElement._firstBuild 
package:flutter/โ€ฆ/widgets/framework.dart:4068
#3      ComponentElement.mount 
package:flutter/โ€ฆ/widgets/framework.dart:3919
#4      Element.inflateWidget 
package:flutter/โ€ฆ/widgets/framework.dart:3101
...
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

โ•โ•โ•โ•โ•โ•โ•โ• Exception caught by rendering library โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
The _ScaffoldLayout custom multichild layout delegate forgot to lay out the following child:
User-created ancestor of the error-causing widget was
    Scaffold 
lib/โ€ฆ/authentication/login.dart:142
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

โ•โ•โ•โ•โ•โ•โ•โ• Exception caught by widgets library โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
'package:flutter/src/widgets/framework.dart': Failed assertion: line 4398 pos 14: '_dependents.isEmpty': is not true.
User-created ancestor of the error-causing widget was
    MaterialApp 
lib/main.dart:85
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

โ•โ•โ•โ•โ•โ•โ•โ• Exception caught by scheduler library โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
'package:flutter/src/widgets/framework.dart': Failed assertion: line 2346 pos 16: '!_dirtyElements[index]._active || _dirtyElements[index]._debugIsInScope(context)': is not true.
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
question

All 2 comments

For now, my solution -

onPressed: () {
  Navigator.push(
    context,
    EnterExitRoute(
        exitPage: BlocProvider.value(
          value:
              BlocProvider.of<LoginBloc>(context),
          child:LoginPage()),
        enterPage:  RegistrationNameCompany(),
        ),
  );
}

Hi @paqio ๐Ÿ‘‹
Thanks for opening an issue!

Only blocs that are provided above MaterialApp are available across routes. Your solution is correct because you need to re-provide the bloc to the route in order for it to be part of the route context. You can read more about this here ๐Ÿ‘

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tigranhov picture tigranhov  ยท  3Comments

krusek picture krusek  ยท  3Comments

hivesey picture hivesey  ยท  3Comments

RobPFarley picture RobPFarley  ยท  3Comments

rsnider19 picture rsnider19  ยท  3Comments