Hoo
Hoo

Reputation: 1840

What is the correct way to get the value which has been stored using sharedPreferences to widget?

What is the correct way to get the value which has been stored using sharedPreferences to widget?

PageA

 @override
  void initState() {
    super.initState();
    sharedPreferences = SampleSharedPreferences().getData();
    sharedPreferences.then((onValue) {
      name = onValue.name;  // I debug this line, I can see the value
    });
  }

     @override
      Widget build(BuildContext context) {
        return Scaffold(
            body: SingleChildScrollView(
                child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Padding(
              child: Text(
                name,
                style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
              ),
              padding: const EdgeInsets.only(top: 14.0, left: 14.0),
            ),
              ....

Error

A non-null String must be provided to a Text widget.
'package:flutter/src/widgets/text.dart':
Failed assertion: line 269 pos 10: 'data != null'

I guess is because the widget is calling first before SharedPreferences get called? What is the proper way to write it?

SampleSharedPreferences

class SampleSharedPreferences {

  static const NAME = "user_name";

  void store(ABC abc) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setString(NAME, name);
  }

  Future<ABC> getUser() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    ABC abc = new ABC();
    abc.name = prefs.getString(USER_NAME);
    return abc;
  }
}

Upvotes: 0

Views: 60

Answers (2)

Ravinder Kumar
Ravinder Kumar

Reputation: 7990

Your problem is simple sharedPreferences takes some time to fetch values saved in it, by the time it fetches the value build function is already called and hence it gives you A non-null String must be provided to a Text widget. this error.

Solution: so either try to initialize your Srting name=""

or check,

Text(
  name!=null? name:'',
  style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
  ),

and whenever sharepref is ready with your String try to call setSate,

 sharepref .then((onValue) {
      setState(() {
        mUserInfo = onValue;
      });
    }

Upvotes: 0

Mohamad Assem Nasser
Mohamad Assem Nasser

Reputation: 1109

SharedPrefernces takes some time to load, so use FutureBuilder:

@override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Padding(
              child: FutureBuilder(
                future: getUser, // a previously-obtained Future<String> or null
                builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
                  switch (snapshot.connectionState) {
                    case ConnectionState.none:
                      return Text('Press button to start.');
                    case ConnectionState.active:
                    case ConnectionState.waiting:
                      return CircularProgressIndicator();
                    case ConnectionState.done:
                      if (snapshot.hasError)
                        return Text('Error: ${snapshot.error}');
                      return Text(
                        snapshot.data,
                        style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                      );
                  }
                  return null; // unreachable
                },
              ),
              padding: const EdgeInsets.only(top: 14.0, left: 14.0),
            ),
          ],
        ),
      ),
    );
  }

Upvotes: 1

Related Questions