Assigning the sharedPreference value to a variable within the build

Issue

I have successfully stored a value as a string in the localStorage as below:

var acceptedCompany = jsonEncode('${item.company!.name!}');
print('storedCompany: $acceptedCompany'); // succesfully prints value as 'abc'
await sharedPref.save('savedCompany', acceptedCompany);

And now I want to read the stored value from another screen and assign it to a variable which I can then bind to my Text() widget. I have successfully accessed the value within my console. However when I try to assign the stored value to a variable, I get an error:

"Instance of Future<dynamic>"

Here is how am getting back the stored value:

class _SideBarState extends State < SideBar > {
  SharedPref sharedPref = SharedPref();
  var savedCompany;
  String key = 'storedCompany';

  @override
  @override
  void didChangeDependencies() {
    getCompany();
    super.didChangeDependencies();
  }

  getCompany() async {
    savedCompany = await sharedPref.read(key);
    print('getComp: $savedCompany'); // this returns the stored value i.e 'abc' but I can't assign this to the Text widget
  }

  @override
  Widget build(BuildContext context) {
    var savedCompany2 = getCompany();
    print('getComp2: $savedCompany2'.toString()); // generates an error 'Instance of Future<dynamic>'
    return Text($savedCompany2);
  }
}

My SharedPref Class looks like this:

read(key) async {
  final prefs = await SharedPreferences.getInstance();
  final value = prefs.getString(key) ? ? 0;
  // print('retrievedValue: ' + '$value');
  return value;
}

save(key, value) async {
  final prefs = await SharedPreferences.getInstance();
  // prefs.setString(key, json.encode(value));
  prefs.setString(key, value);
  // print('savedToken:' + '$key');
}

How can I access the sharedPreference value and assign it to the variable that I can then bind to the Text widget?

Solution

To overcome the problem, you can either set the value after the initState or using FutureBuilder.

FutureBuilder:

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

  @override
  State<SideBar> createState() => _SideBarState();
}

class _SideBarState extends State<SideBar> {

  SharedPref sharedPref = SharedPref();
  String key = 'storedCompany';

  Future<String> getCompany() async {
    return await sharedPref.read(key);
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<String>(
      future: getCompany(),
      builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
        if (snapshot.hasData) {
          return Text('Result: ${snapshot.data}');
        } else if (snapshot.hasError) {
          return Text('Error: ${snapshot.error}');
        } else {
          return Center(child: CircularProgressIndicator());
        }
      },
    );
  }
}

After initState():

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

  @override
  State<SideBar> createState() => _SideBarState();
}

class _SideBarState extends State<SideBar> {

  SharedPref sharedPref = SharedPref();
  String key = 'storedCompany';

  String? _companyName;

  Future<void> getCompany() async {
    var name = await sharedPref.read(key);
     
    setState(() {
      _companyName = name;
    });
  }

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

  @override
  Widget build(BuildContext context) {
    if(_companyName == null) return Center(child:CircularProgressIndicator());
    return Text(_companyName!);
  }
}

Answered By – ישו אוהב אותך

Answer Checked By – David Marino (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *