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

Fix StoreProvider.of for Reified types #15

Closed
lwasylkowski opened this issue Mar 5, 2018 · 12 comments · Fixed by #20
Closed

Fix StoreProvider.of for Reified types #15

lwasylkowski opened this issue Mar 5, 2018 · 12 comments · Fixed by #20

Comments

@lwasylkowski
Copy link

I'm repeatedly getting

I/flutter ( 9311): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 9311): The following NoSuchMethodError was thrown building StoreConnector<int, Store<int>>(dirty):
I/flutter ( 9311): The getter 'store' was called on null.
I/flutter ( 9311): Receiver: null
I/flutter ( 9311): Tried calling: store

error when trying to use StoreBuilder or StoreConnector in the hierarchy. My app widget builds the rest like this:

@override
Widget build(BuildContext context) {
  return new StoreProvider<int>(
    store: new Store<int>(
            (i, action) => i + 1,
        initialState: 0
    ),
    child: new MaterialApp(
      title: 'App',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new Scaffold(
          appBar: new AppBar(
            title: new Text("App"),
          ),
          body: new MainScreen(),
    ),
  );
}

I can't get it to work, I understand StoreProvider is a simple InheritedWidget, but even if I try to manually call new StoreProvider.of(context) in a widget down the tree, I get null. I don't understand, since I've created dead simple inherited widget and placed it instead of StoreProvider and I could fetch it with of() method without issues (I almost did a copy-paste from the StoreProvider class).

The int state and inline reducer is just a result of me trying to simplify the things as much as I can, with no luck. Any idea why would it be like this?

@brianegan
Copy link
Owner

brianegan commented Mar 5, 2018

Hrm, interesting case.

I think the problem might be: you're constantly rebuilding a new Store in the build method and handing that off to the StoreProvider, and the library might not handling that properly.

So whenever you do a Hot Reload or that build method is called again, it's probably rebuilding the Store and stuff is going wrong.

I'll take a deeper look. For now, could you please try moving the Store out of the build method into an initState and see if it works?

@lwasylkowski
Copy link
Author

I'm not sure what you mean, but I moved the app to a stateful widget, created the entire tree (starting from StoreProvider in state's build method, but passed store field created in initState -- still no luck.

I'll add that initially I created store field inline final store = ..., much like in your sample actually. If you don't have more ideas, maybe I'll clean it up/rewrite and paste entire app for you to run?

@brianegan
Copy link
Owner

Yah that would be great... I haven't run into that issue before :(

@lwasylkowski
Copy link
Author

import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux/redux.dart';

void main() => runApp(new TestApp());

class TestApp extends StatelessWidget {

  final store = new Store<int>(
        (state, action) => state + 1,
    initialState: 0,
  );

  @override
  Widget build(BuildContext context) =>
      new StoreProvider<int>(
          store: this.store,
          child: new MaterialApp(
            title: "App",
            theme: new ThemeData(
              primarySwatch: Colors.blue,
            ),
            home: new Scaffold(
              appBar: new AppBar(
                title: new Text("App"),
              ),
              body: new MainScreen(),
            ),
          )
      );
}

class MainScreen extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return new StoreConnector<int, String>(
      converter: (state) => state.toString(),
      builder: (context, text) =>
      new Center(
        child: new Text(text),
      ),
    );
  }
}

Here it is. Only two new dependencies in pubspec:

redux: ^2.1.1
flutter_redux: ^0.3.5

Flutter doctor:

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, v0.1.5, on Mac OS X 10.13.3 17D102, locale en-PL)
[✓] Android toolchain - develop for Android devices (Android SDK 27.0.3)
[✓] iOS toolchain - develop for iOS devices (Xcode 9.2)
[✓] Android Studio
[✓] Android Studio
[✓] Android Studio (version 3.0)
[✓] IntelliJ IDEA Community Edition (version 2017.3.4)
[!] VS Code (version 1.19.2)
[✓] Connected devices (1 available)

! Doctor found issues in 1 category.

@brianegan
Copy link
Owner

brianegan commented Mar 5, 2018

Yep, you found a bug! This is an interesting problem with how Dart reifies types, and my current solution doesn't quite work unfortunately ;(

For now, please use new StoreProvider instead of new StoreProvider<int> and it should work!

Thanks for the report, good catch!

@brianegan brianegan changed the title Using StoreBuilder or StoreConnector results in a NoSuchMethodError Fix StoreProvider.of for Reified types Mar 5, 2018
@brianegan
Copy link
Owner

brianegan commented Mar 6, 2018

As a heads up: Got a workaround going to properly support generics. I'll try to push it up soon-ish!

@santiagofm
Copy link
Contributor

I encountered the same issue with the example project and just found out it happens if i have the dart 2 preview enabled.. I'm not sure if it's the same issue but disabling the preview fixes it

Cheers

@brianegan
Copy link
Owner

brianegan commented Mar 6, 2018

Thanks for the report! I'm actually working on a few changes that fix both this bug and adds Dart2 support :)

@santiagofm
Copy link
Contributor

Awesome !! keep up the good work!

@xrigau
Copy link

xrigau commented Mar 18, 2018

Same issue here, glad I'm not the only one 😅

Meanwhile I replaced the dependency in the pubspec.yaml file with:

  flutter_redux:
    git:
      url: git://github.com/brianegan/flutter_redux.git
      ref: 0.4.0

and everything works again, thanks for your work @brianegan 💯

@brianegan
Copy link
Owner

brianegan commented Mar 19, 2018

Sure thing! Sorry for the delay in publishing the new version, test coverage isn't quite working with Dart 2 and I'd like to hold off until that's fixed.

That branch should totally work, however -- so feel free to play around and report issues!

@xrigau
Copy link

xrigau commented Mar 19, 2018

Will do!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants