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

ProviderScope override "forgets" the StreamProvider value during navigation #10

Closed
RobertBrunhage opened this issue Jun 24, 2020 · 6 comments
Assignees
Labels
bug Something isn't working

Comments

@RobertBrunhage
Copy link
Contributor

Describe the bug
When creating a StreamProvider with a value of Stream.value(null) and then override it in another page then this should only be null until it is set. Right now it seems like it resets when navigating with an animation.

Have added a deugPrint(user.name) to easily see the behavior in the console.

To Reproduce
Click the ListTile and look at the log.

class User {
  String id;
  String name;

  User.empty() {
    id = "";
    name = "";
  }

  User.other() {
    id = "12345";
    name = "Tester";
  }

  @override
  bool operator ==(Object other) => identical(this, other) || other is User && runtimeType == other.runtimeType && name == other.name;

  @override
  int get hashCode => name.hashCode;
}

final userProvider = StreamProvider<User>((ref) {
  return Stream.value(User.empty());
});
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ProviderScope(
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
          visualDensity: VisualDensity.adaptivePlatformDensity,
        ),
        home: PageOne(),
      ),
    );
  }
}

class PageOne extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ProviderScope(
      // This override is causing the issue.
      // If this override would be at the material app
      // then the debugPrint will always print Tester
      overrides: [
        userProvider.overrideAs(
          StreamProvider(
            (ref) => Stream.value(User.other()),
          ),
        ),
      ],
      child: Scaffold(
        body: OpenContainer(
          closedElevation: 4,
          closedBuilder: (BuildContext context, VoidCallback openContainer) {
            return Consumer((context, read) {
              final user = read(userProvider).data == null ? User.empty() : read(userProvider).data.value;
              debugPrint(user.name);
              return Container(
                height: 100,
                child: ListTile(
                  title: Text(user.name),
                ),
              );
            });
          },
          openBuilder: (context, __) {
            return Scaffold();
          },
        ),
      ),
    );
  }
}

Do not forget to add dependencies in .yaml

  animations: ^1.1.0
  flutter_riverpod: ^0.1.0

Expected behavior
When running this the debugPrint(user.name) should not be empty during navigation.

@RobertBrunhage RobertBrunhage added the bug Something isn't working label Jun 24, 2020
@RobertBrunhage RobertBrunhage changed the title ProviderScope override weird behavior ProviderScope override "forgets" the StreamProvider value during navigation Jun 24, 2020
@rrousselGit
Copy link
Owner

rrousselGit commented Jun 24, 2020

Oh, I know

It's the good-old "a provider is scoped to its route"

By using ProviderScope inside a route, the override is not accessible to other routes.

@rrousselGit
Copy link
Owner

In your case, this happens not because of navigation, but because of Overlay

During the transition, your Consumer is rendered above PageOne for a moment.

@RobertBrunhage
Copy link
Contributor Author

RobertBrunhage commented Jun 24, 2020

Ohh I see but then what would be a good solution for that? As that value is used by both and I can not put it above the MaterialApp as let's say I have no access to the value there. (Getting the user after sign in).

It feels weird to wrap both the ClosedBuilder return value and the OpenBuilder return value with a override

@rrousselGit
Copy link
Owner

rrousselGit commented Jun 24, 2020

Honestly, this is more of an issue with Overlay than riverpod. flutter/flutter#36220 should be fixed.
Ideally by merging flutter/flutter#39104

As for how to fix it... Maybe consume the value above the OpenContainer and re-override ProviderScope inside the builder with the true value

@RobertBrunhage
Copy link
Contributor Author

Yeah did that and it works, thanks for the help!

@samu-developments
Copy link

Honestly, this is more of an issue with Overlay than riverpod. flutter/flutter#36220 should be fixed.
Ideally by merging flutter/flutter#39104

As for how to fix it... Maybe consume the value above the OpenContainer and re-override ProviderScope inside the builder with the true value

Hi, I'm trying to implement this solution, however I'm getting this error:
Unsupported operation: ProviderScope was rebuilt with a different ProviderScope ancestor.
along with:

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
Updated the list of overrides with providers that were not overriden before
'package:riverpod/src/framework/container.dart':
Failed assertion: line 247 pos 9: 'unusedOverrides.isEmpty'
final Widget closedScreen;

@override
  Widget build(BuildContext context) {
    return Consumer((context, watch) {
      final bool favorited = watch(favoritedProvider);
      return OpenContainer(
        closedBuilder: (_, __) {
          return ProviderScope(
            overrides: [
              favoritedProvider.overrideWithValue(favorited),
            ],
            child: closedScreen,
          );
        },
        openBuilder: (_, __) {
          return Container();
        },
      );
    });

The closedScreen builds fine on initial build, only during animation (when closedScreen is tapped) is the error thrown. What am I doing wrong? Thanks

flutter_riverpod: ^0.6.1
animations: ^1.1.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants