Home > Software design >  Add value from Sharedpreferences in variable (stateful widget)
Add value from Sharedpreferences in variable (stateful widget)

Time:10-22

I saved the data using SharedPreferences, when my app is starting i try check type of user "client" or "company" after that wil be shown screen.

Future<void> setTypeClient() async {
    final _storage = SharedPreferences.getInstance();
    final storage = await _storage;
    storage.setString('type_user_db', 'client');
  }

My app is starting

I have variable

var typeUser = ' ' ; and use it when I determine which screen to display

Аfter I get the data from SharedPreferences, I need to put value in this variable

But i have an error, cause variable remains empty

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

import '../views/home_view.dart';

import '../views/auth/client_auth_view.dart';
import '../views/auth/company_auth_view.dart';
import '../views/auth/company_reg_view.dart';

import '../views/client/client_view.dart';
import '../views/company/company_view.dart';

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

  @override
  Widget build(BuildContext context) {
    return const MyAppBody();
  }
}

class MyAppBody extends StatefulWidget {
  const MyAppBody({Key? key}) : super(key: key);

  @override
  State<MyAppBody> createState() => _MyAppBodyState();
}

class _MyAppBodyState extends State<MyAppBody> {
  
  Future<void> getTypeUser() async {
    final storage = await SharedPreferences.getInstance();
    final type = storage.getString('type_user_db');
    setState(() {
      typeUser = type!;
    });
  }

  var typeUser = '';

  Map<String, Widget> screenByUser = {
    'client': const ClientView(),
    'company': const CompanyView(),
  };

  bool isLogOut = true;

  @override
  void initState() {
    if (FirebaseAuth.instance.currentUser != null) {
      getTypeUser();
      setState(() {
        isLogOut = false;
      });
      super.initState();
    } else {
      return;
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Well Plus',
      debugShowCheckedModeBanner: false,
      routes: {
        '/main': (context) => const HomeView(),
        '/auth_client': (context) => const AuthClientView(),
        '/auth_company': (context) => const AuthCompanyView(),
        '/reg_company': (context) => const RegCompanyView(),
        '/client': (context) => const ClientView(),
        '/company': (context) => const CompanyView(),
      },
      home: isLogOut ? const HomeView() : screenByUser[typeUser],
    );
  }
}

update

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

import '../views/home_view.dart';

import '../views/auth/client_auth_view.dart';
import '../views/auth/company_auth_view.dart';
import '../views/auth/company_reg_view.dart';

import '../views/client/client_view.dart';
import '../views/company/company_view.dart';

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

  @override
  Widget build(BuildContext context) {
    return const MyAppBody();
  }
}

class MyAppBody extends StatefulWidget {
  const MyAppBody({Key? key}) : super(key: key);

  @override
  State<MyAppBody> createState() => _MyAppBodyState();
}

class _MyAppBodyState extends State<MyAppBody> {
  
  Future<void> getTypeUser() async {
    final storage = await SharedPreferences.getInstance();
    final type = storage.getString('type_user_db');
    setState(() {
      typeUser = type!;
    });
  }

  var typeUser = '';

  Map<String, Widget> screenByUser = {
    'client': const ClientView(),
    'company': const CompanyView(),
  };

  bool get isLogOut => typeUser.isEmpty;

  @override
  void initState() {
    if (FirebaseAuth.instance.currentUser == null) {
      getTypeUser();
      setState(() {
        isLogOut = false;
      });
      super.initState();
    } else {
      return;
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Well Plus',
      debugShowCheckedModeBanner: false,
      routes: {
        '/main': (context) => const HomeView(),
        '/auth_client': (context) => const AuthClientView(),
        '/auth_company': (context) => const AuthCompanyView(),
        '/reg_company': (context) => const RegCompanyView(),
        '/client': (context) => const ClientView(),
        '/company': (context) => const CompanyView(),
      },
      home: isLogOut ? const HomeView() : screenByUser[typeUser],
    );
  }
}

error in

 setState(() {
        isLogOut = false;
      });

error screen

enter image description here

CodePudding user response:

To solve this issue we have to clarify synchronous and asynchronous operations.

Initialating you widget with initState and next build method called one by one in synchronous way but getUser is asynchronous.

This is meant that you specify isLogOut before you setting the typeUser. Instead of manually setting the isLogOut property just to change it to getter

bool get isLogOut => typeUser.isEmpty;

And you can guarantee the property will be correct all the time when you requests it.

Enjoy coding

  • Related