String stored in Shared Preferences is not loading at first in Flutter app

Issue

I have a project management app where the details of the project are displayed after pressing the ‘more’ icon button on a card. The details to be displayed include the project name and due date that are fetched from the database and then stored locally using shared preferences. Both the ‘setString’ and ‘getString are working well but upon loading the project details page, the details do not appear at first. They only display after hot reloading the app while that page is active. Below is the code of the project details app:

import 'package:flutter/material.dart';
import 'package:mne/Actual%20Tasks/activity_widget.dart';
import 'package:mne/UserTasks/task_widget.dart';
import 'package:shared_preferences/shared_preferences.dart';

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

  @override
  State<ProjectTask> createState() => _ProjectTaskState();
}

class _ProjectTaskState extends State<ProjectTask> {
  String pname;
  String pdesc;
  String pdue;

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

  Future<Null> _fetchData() async {
    WidgetsFlutterBinding.ensureInitialized();
    SharedPreferences localStorage = await SharedPreferences.getInstance();
    pname = localStorage.getString('project_name');
    pdesc = localStorage.getString('project_desc');
    pdue = localStorage.getString('project_due');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          iconTheme: const IconThemeData(color: Colors.black),
          backgroundColor: Colors.white,
          automaticallyImplyLeading: true,
          centerTitle: true,
          title: const Text('Project Details',
              style: TextStyle(color: Colors.black))),
      body: SingleChildScrollView(
        child: Column(children: [
          Container(height: 10, color: Colors.transparent),
          // for image
          Container(
            width: 330,
            child: Image.asset('assets/images/projectbanner.png'),
          ),
          //for project name
          Container(
              padding: const EdgeInsets.only(bottom: 25, top: 15),
              child: Row(children: [
                Container(
                  padding: const EdgeInsets.only(left: 20, right: 145),
                  child: Text(pname ?? '',
                      style: const TextStyle(
                          color: Colors.black,
                          fontWeight: FontWeight.bold,
                          fontSize: 16)),
                ),
                Container(
                    padding: const EdgeInsets.only(right: 10, top: 8),
                    child: const Icon(Icons.calendar_month_outlined)),
                RichText(
                    text: TextSpan(children: [
                  const TextSpan(
                      text: 'Due: ',
                      style: TextStyle(
                          fontSize: 12,
                          fontWeight: FontWeight.bold,
                          color: Colors.black)),
                  TextSpan(
                      text: pdue ?? '',
                      style: const TextStyle(fontSize: 12, color: Colors.black))
                ])),
              ])),
          // for description title
          Container(
              alignment: Alignment.centerLeft,
              padding: const EdgeInsets.only(left: 20, bottom: 20),
              child: const Text('Description',
                  style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16))),
          // for actual desc
          Container(
              padding: const EdgeInsets.only(left: 20),
              alignment: Alignment.centerLeft,
              child: Text(
                pdesc ?? '',
                style: const TextStyle(color: Colors.grey),
              )),
          // for task title
          Container(
              padding: const EdgeInsets.only(left: 20, top: 20, bottom: 20),
              alignment: Alignment.centerLeft,
              child: const Text('Tasks',
                  style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16))),
          // for task widget
          Container(height: 630, child: const ActivityWidget()),
        ]),
      ),
    );
  }
}

This image shows what it looks like when it first loads:
on first loading this is what it looks like

This is what it is supposed to look like after hot reloading:
This is what it looks like after hot reloading

How can I make it so that it displays the information right away? Any help is appreciated.

Solution

Change your fetchData function to this:

  Future<Null> _fetchData() async {
    WidgetsFlutterBinding.ensureInitialized();
    SharedPreferences localStorage = await SharedPreferences.getInstance();
    setState(() {
      pname = localStorage.getString('project_name');
      pdesc = localStorage.getString('project_desc');
      pdue = localStorage.getString('project_due');
    })
  }

Answered By – manhtuan21

Answer Checked By – Pedro (FlutterFixes Volunteer)

Leave a Reply

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