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

First signal update doesn't usually get listened to #266

Closed
SPiercer opened this issue May 15, 2024 · 13 comments
Closed

First signal update doesn't usually get listened to #266

SPiercer opened this issue May 15, 2024 · 13 comments
Labels
bug Something isn't working

Comments

@SPiercer
Copy link

I have this simple signal i've created to act as a flag/guard to do auth navigation

  @override
  Widget build(BuildContext context) {
    routerGuardSignal.listen(context, () {
      final isUserLoggedIn = routerGuardSignal.value;
      log(isUserLoggedIn.toString());
      while (navKey.currentState!.canPop()) {
        navKey.currentState!.pop();
      }
      if (isUserLoggedIn == true) {
        navKey.currentState!.pushNamed(MainScreen.routeName);
      } else if (isUserLoggedIn == false) {
        navKey.currentState!.pushNamed(LoginScreen.routeName);
      }
    });

this is placed under the material app build context

and from the splash screen i do my check and then i do

routerGuardSignal.value = true or false

sometimes this call make the listener cb invoked and sometimes not

@rodydavis
Copy link
Owner

It will only be called if the widget is mounted where the listener is created

@rodydavis
Copy link
Owner

I would suggest an effect outside of the build method to ensure it calling no matter what

@SPiercer
Copy link
Author

SPiercer commented May 15, 2024

It will only be called if the widget is mounted where the listener is created

But shouldn't the widget be mounted since this is the root widget ?

@rodydavis
Copy link
Owner

That should be the case, although I have had weird behavior before with the root widget being mounted.

Can you reproduce a minimal example to test? I'll added it to the widget tests to make sure it's valid.

@SPiercer
Copy link
Author

SPiercer commented May 15, 2024

That's minimal enough i can drop everything here in one file

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MyApp());
}

final routerGuardSignal = Signal<bool?>(null);


class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

final navKey = GlobalKey<NavigatorState>();

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    routerGuardSignal.listen(context, () {
      while (navKey.currentState?.canPop() == true) {
        navKey.currentState?.pop();
      }
      final isUserLoggedIn = routerGuardSignal.value;
      if (isUserLoggedIn == true) {
        navKey.currentState!.pushNamed('/main');
      } else if (isUserLoggedIn == false) {
        navKey.currentState!.pushNamed('/login');
      }
    });
    return MaterialApp(
      navigatorKey: navKey,
      routes: {
        '/splash': (_) => const SplashScreen(),
        '/main': (_) => const Scaffold(body:Text('Main')),
        '/login': (_) => const Scaffold(body:Text('Login')),
      },
      initialRoute: '/splash',
    );
  }
}

class SplashScreen extends StatefulWidget {
  const SplashScreen({super.key});

  @override
  State<SplashScreen> createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {
  @override
  void initState() {
    Future.delayed(const Duration(seconds: 2), () async {
     routerGuardSignal.value = true;
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
        body: Text('Splash')
    );
  }
}

@rodydavis
Copy link
Owner

What is the expected error and what steps do I need to do to reproduce it?

Also is it fixed with an effect or subscribe in initState?

@SPiercer
Copy link
Author

Sorry for missing that

Steps to Reproduce

  1. Run the code
  2. wait for the app to open the splash screen
  3. wait two seconds

Expected behavior: App navigates to main page route

Actual behavior: Gets stuck on splash screen


and i tried adding the effect in a separate function away from the context and it worked

@rodydavis
Copy link
Owner

Definitely sounds like a bug or implementation issue, I think I know what is causing it.

@rodydavis rodydavis added the bug Something isn't working label May 16, 2024
@SPiercer
Copy link
Author

Any updates on this ?

@rodydavis
Copy link
Owner

Just got back from my honeymoon so will be looking at it soon!

@SPiercer
Copy link
Author

SPiercer commented May 23, 2024 via email

@rodydavis
Copy link
Owner

Found a fix, and will include on the next update!

@iSaqibShafique
Copy link

Just got back from my honeymoon so will be looking at it soon!

🎉 Congratulations, sir, on your marriage! 💍 Wishing you a lifetime filled with love, joy, and endless adventures together. May your journey as a married couple be as enchanting as a fairytale and as vibrant as the brightest stars in the sky. Here's to a future overflowing with happiness, laughter, and unforgettable moments! ❤️

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