Bloc: Event method is not defined for the child class of the BlocProvider

Created on 13 Feb 2020  路  4Comments  路  Source: felangel/bloc

Describe the bug

The events defined in the bloc cannot be accessed by the direct child component it wraps:

class App extends StatelessWidget {
  final PtvRepository ptvRepository;

  App({Key key, @required this.ptvRepository})
      : assert(ptvRepository != null),
        super(key: key);

  @override
  Widget build(BuildContext context) {
    return BlocProvider<OnboardingBloc>(
      create: (context) => OnboardingBloc(ptvRepository: ptvRepository),
      child: MaterialApp(home: HomePage()),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(
        // Button to nav to onboarding
        child: RaisedButton(
          onPressed: () async {
            BlocProvider.of<OnboardingBloc>(context).add(FetchRoutes()); // <---- this is the problem
            await Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) => OnBoarding(),
              ),
            );
          },
          child: Text('Add Route'),
        ),
      ),
    );
  }
}
Compiler message:
lib/main.dart:48:58: Error: The method 'FetchRoutes' isn't defined for the class 'HomePage'.
 - 'HomePage' is from 'package:ptv/main.dart' ('lib/main.dart').
Try correcting the name to the name of an existing method, or defining a method named 'FetchRoutes'.
            BlocProvider.of<OnboardingBloc>(context).add(FetchRoutes());
                                                         ^^^^^^^^^^^

There is no mention in the documentation or the Weather tutorial (which I am using as a reference) as to why this method needs to be defined in the widget.

I had the fetch and populating a list working fine until I tried to refactor into pages and add a second fetch method.

Here is the whole repo: https://github.com/lockykeaney/flutter-ptv/tree/refactor

I will assume that the problem here is a misunderstanding of the bloc principles, but I cannot find any examples or tutorials that fit my use case. I want to hit a button, it runs and API call and displays a list. Then when tapping a list item, it passes the id to another API call to populate another list.

I cannot find any reference about working with API lists and multiple calls to different end points, and then creating a state which I can save to device. I read somewhere to each bloc should represent a feature, the onboarding feature will require a few API calls to create a "journey" to be saved to the device.

Thanks.

question

Most helpful comment

@felangel Holy Moly that was so quick! Thank you!

For future knowledge, you changed import to part, what exactly does that do? Does that tell the file to also export what it has imported?

You are doing a great job on this package and documentation, Thank you for time.

All 4 comments

Hi @lockykeaney 馃憢
Thanks for opening an issue!

I opened a pull request to resolve the issue. The problem was your weren't exporting your events/states from the bloc nor were you importing the events directly from the widget. Hope that helps!

@felangel Holy Moly that was so quick! Thank you!

For future knowledge, you changed import to part, what exactly does that do? Does that tell the file to also export what it has imported?

You are doing a great job on this package and documentation, Thank you for time.

No problem haha! Part just means pretend like the code is part of the same file so when we import the bloc we also import the events and states. Thanks so much for the kind words, I really appreciate it! 馃檹

@lockykeaney the part tells the compiler that the file referenced after the word is part of the same file. The other "part" of the file is broken into the event and state classes, so you'll notice in the event file that it has part of at the top.

Was this page helpful?
0 / 5 - 0 ratings