Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

flutter: route into different pages according to different status

Tags:

flutter

dart

Trying to do a redirect depending on user status in my app (logged in or not), but it won't work as I want it to as I am not sure how to get the BuildContext inside the method.

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:t2/helpers/currentuser.dart';

import 'screens/dashboard.dart';
import 'screens/login.dart';

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

CurrentUser user = new CurrentUser();

Future checkActiveUser() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();

  user.usr = prefs.get('usr');
  user.pwd = prefs.get('pwd');
  if (user.usr.length == 0 && user.pwd.length == 0) {
    user.isLoggedIn = false;
    Navigator.of(x).pushNamedAndRemoveUntil('/dashboard', (Route<dynamic> route) => false);
  } else {
    // Send to login screen
    user.isLoggedIn = false;
    Navigator.of(x).pushNamedAndRemoveUntil('/login', (Route<dynamic> route) => false);
  }

  return user.isLoggedIn;

  /*
// How to read/write to local storage
int counter = (prefs.getInt('counter') ?? 0) + 1;
print('Pressed $counter times.');
prefs.setInt('counter', counter);
*/
}

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        title: 'Flutter Demo',
        theme: new ThemeData(
          // This is the theme of your application.
          //
          // Try running your application with "flutter run". You'll see the
          // application has a blue toolbar. Then, without quitting the app, try
          // changing the primarySwatch below to Colors.green and then invoke
          // "hot reload" (press "r" in the console where you ran "flutter run",
          // or press Run > Flutter Hot Reload in IntelliJ). Notice that the
          // counter didn't reset back to zero; the application is not restarted.
          primarySwatch: Colors.blue,
        ),
        home: new MyHomePage(),
        routes: <String, WidgetBuilder>{
          '/dashboard': (BuildContext context) => new Dashboard(),
          '/login': (BuildContext context) => new Login()
        });
  }
}

class MyHomePage extends StatelessWidget {

   var isLoggedIn = checkActiveUser();

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text('Demo Building'),
        ),
        body: new Container(
            child: new Center(
          child: new Column(
            children: <Widget>[new Text('DASHBOARD')],
          ),
        )));
  }
}

If you have suggestions for a different approach, I'm all ears! I basically want to run this check on app load and redirect accordingly.

Regards, Bob

UPDATED CODE: Tried the suggestion from Hadrien, and got a step closer. It now runs and I get contact access but, get the following error:

'Navigator operation requested with a context that does not include a Navigator. The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget.'

This is the updated code:

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:t2/helpers/currentuser.dart';

import 'screens/dashboard.dart';
import 'screens/login.dart';

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

CurrentUser user = new CurrentUser();

checkActiveUser(BuildContext context) async {
  SharedPreferences prefs = await SharedPreferences.getInstance();

try {
  user.usr = prefs.get('usr');
  user.pwd = prefs.get('pwd');

  if (user.usr.length == 0 && user.usr.length == 0) {
    user.isLoggedIn = false;
    Navigator
        .of(context)
        .pushNamedAndRemoveUntil('/dashboard', (Route<dynamic> route) => false);
  } else {
      throw new Exception('No user data found');
  }
} catch (e) {
    // Send to login screen
    user.isLoggedIn = false;
    Navigator
        .of(context)
        .pushNamedAndRemoveUntil('/login', (Route<dynamic> route) => false);
}

  /*
// How to read/write to local storage
int counter = (prefs.getInt('counter') ?? 0) + 1;
print('Pressed $counter times.');
prefs.setInt('counter', counter);
*/
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {
  void initState() {
    super.initState();
    checkActiveUser(context);
  }

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Welcome to Flutter',
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('CADSYS'),
        ),
        body: new Center(
          child: new Text('Loading...'),
        ),
      ),
     routes: <String, WidgetBuilder> {
      '/dashboard': (BuildContext context) => new Dashboard(),
      '/login': (BuildContext context) => new Login()
    },
    );
  }
}
like image 823
Robert Benedetto Avatar asked Mar 19 '18 09:03

Robert Benedetto


People also ask

How do you go from one activity to another activity in flutter?

To navigate from one screen to another, you must use the Navigator . Here is an example to navigate on another page which class name is AnotherPage as you may see. Show activity on this post. You have to use navigator.


2 Answers

I would probably do it a little differently... instead of pushing a route inside a function, set the login state inside your StatefulWidget and then set the body based on that.

body: user.isLoggedIn ? new Dashboard() : new Login(),

then elsewhere in your code you'll need to check the active user and do setState((){ user.isLoggedIn = true; }); (or false).

When the login state changes, your view will automatically update with the new Widget.

like image 171
Herohtar Avatar answered Nov 01 '22 01:11

Herohtar


The Navigator come with the MaterialApp widget, so you can only access it from the routes you defined in it and from their child. (Login, Dashboard, MyHomePage).

if you transform your MyHomePage widget into a stateful widget. you will be able to call your checkActiveUser() function inside initState

initState() async {
   super.initState();
   checkActiveUser(context);
}
like image 45
Hadrien Lejard Avatar answered Oct 31 '22 23:10

Hadrien Lejard