0

I want to render the value saved in key of object of SharedPreference Class in the App Bar as Text for which I have to declare the following code in the initState of the widget.

initState() {
    // TODO: implement initState
    super.initState();
    debugPrint("Runed");
    _getPrefs();
    SharedPreferences.getInstance().then((prefs) {
      setState(() => prefs = prefs);
    });
    
  }

My _getPrefs() code is:

 SharedPreferences prefs;

  Future<dynamic> _getPrefs() async {
    prefs = await SharedPreferences.getInstance();
    return prefs;
  }

and my AppBar code is:

appBar: AppBar(
        title: Text(prefs.getString("username")),
        centerTitle: true,
      ),

Body of the widget:

  body: ListView(
        children: [
          FutureBuilder(
              future: _getPrefs(),
              builder: (context, snapshot) {
                if (snapshot.hasData) {
                  return Column(
                    mainAxisAlignment: MainAxisAlignment.start,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      Padding(
                        padding: EdgeInsets.only(left: 5, top: 5, right: 5),
                        child: Container(
                          width: double.infinity,
                          padding: EdgeInsets.only(left: 5),
                          decoration: BoxDecoration(
                            color: Colors.white54,
                            shape: BoxShape.rectangle,
                            borderRadius: BorderRadius.circular(25.0),
                            boxShadow: [
                              BoxShadow(blurRadius: 2, color: Colors.white)
                            ],
                          ),
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: <Widget>[
                              Container(
                                width: 100,
                                height: 100,
                                margin: EdgeInsets.only(
                                    top: 3, left: 10, bottom: 10),
                                decoration: BoxDecoration(
                                  color: Colors.white,
                                  shape: BoxShape.circle,
                                  image: DecorationImage(
                                      image: NetworkImage(
                                          prefs.getString("photoUrl")),
                                      fit: BoxFit.fill),
                                ),
                              ),


                              Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Text(
                                    prefs.getString("username"),
                                    style: TextStyle(
                                        fontSize: 22,
                                        color: Colors.black45,
                                        fontWeight: FontWeight.bold),
                                  ),
                                  Text(prefs.getString("email"))
                                ],
                              ),


                              /*  Text(
                            prefs.getString("email").toString(),
                            style: TextStyle(fontSize: 18, color: Colors.white70),
                          )*/
                            ],
                          ),
                        ),
                      ),
                    ],
                  );
                } else {
                  return Center(child: Text('False'));
                }
              }),
        ],
      ),

I do get the results successfully while navigating from one screen to the screen where I want to render the text in AppBar but some error does show in the console which is annoying. Please help by telling the reason and solution! Erron in console is this:

Reloaded 14 of 873 libraries in 3,092ms.
I/flutter (20249): Runed

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building ProfileDetail(dirty, state: _ProfileDetailState#6aebe):
The method 'getString' was called on null.
Receiver: null
Tried calling: getString("username")

The relevant error-causing widget was: 
  ProfileDetail file:///D:/All%20Data/My%20Projects/Mine%20Created%20Flutter%20Projects/food_delivery_app/lib/main.dart:268:53
When the exception was thrown, this was the stack: 
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1      _ProfileDetailState.build (package:food_delivery_app/ProfileDetails/profileDetail.dart:36:27)
#2      StatefulElement.build (package:flutter/src/widgets/framework.dart:4744:28)
#3      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4627:15)
#4      StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4800:11)
...
════════════════════════════════════════════════════════════════════════════════════════════════════
Bilal Saeed
  • 2,092
  • 8
  • 31
  • do you place the string username at `Text("")`? – Gilang Pratama Dec 03 '20 at 11:23
  • Your code is redundant. You've ran SharedPreferences.getInstance() twice. You would have to use FutureBuilder in this scenario. Wait for SharedPreferences to return the username then display it in the Text widget. This video will help you out: https://www.youtube.com/watch?v=ek8ZPdWj4Qo and take a look at this: https://medium.com/flutterworld/why-future-builder-called-multiple-times-9efeeaf38ba2 – CoderUni Dec 03 '20 at 11:28
  • Well I have used future builder in the body of scaffol but couldn't use Future builder in app bar thats why used this piece of code ``` SharedPreferences.getInstance().then((prefs) { setState(() => prefs = prefs); });``` in the initState method. I'm updating my question with the body of Widget as well. – Bilal Saeed Dec 03 '20 at 11:47

1 Answers1

2

The problem is that SharedPreferences.getInstance is async, but you are calling it in a sync method where you cannot await. Therefore, your AppBar is being built before SharedPreferences.getInstance returns, meaning prefs is null.

A simple solution is to null check prefs and return a blank or default string until setState is called with a non-null prefs.

appBar: AppBar(
  title: Text(prefs?.getString("username") ?? ''),
  centerTitle: true,
),
Lee3
  • 2,882
  • 1
  • 11
  • 19