Integrate Provider with SharedPreferences to save and get Provider data

Issue

The list which stores the task data is integrated with provider for state management, but once I close the app and reopen it again, all tasks vanish.
With resources, I got to know about SharedPreferences.

How do I go about saving and getting the data using shared preferences. I have given the code a try, but does not seem to work in my favor.

void saveData() async {
    final prefs = await SharedPreferences.getInstance();
    final String encodedData = Task.encode(tasks);
    await prefs.setString('task_data', encodedData);
  }

  void getData() async {
    final prefs = await SharedPreferences.getInstance();
    final String taskString = prefs.getString('task_data').toString();
    List<Task> tasksData = Task.decode(taskString);
    _tasks = tasksData;
  }

encode() and decode() functions help in mapping List to String and String to List respectively.

static String encode(List<Task> tasks) {
    return jsonEncode(
      tasks.map<Map<String, dynamic>>((task) => Task.toMap(task)).toList(),
    );
  }

  static List<Task> decode(String tasks) {
    var data = (jsonDecode(tasks) as List<dynamic>?);
    if (data != null) {
      return (jsonDecode(tasks) as List<dynamic>?)!.map<Task>((task) {
        return Task.fromJson(task);
      }).toList();
    } else {
      return <Task>[];
    }
  }

The Task list in displayed using ListView.

Widget build(BuildContext context) {
    return Consumer<TaskData>(
      builder: (context, taskData, child) {
        taskData.getData();
        return ListView.builder(
          itemCount: taskData.taskCount,
          itemBuilder: (context, index) {
            taskData.sortTaskList();
            final task = taskData.tasks[index];
            return TaskTile(
              taskTitle: task.name,
              isChecked: task.isDone,
              checkboxCallBack: (checkBoxState) async {
                taskData.upDateTask(task);
                taskData.saveData();
              },
              longPressCallBack: () async {
                taskData.removeTask(task);
                taskData.saveData();
              },
            );
          },
        );
      },
    );
  }

Solution

I am expecting that you’re using ChangeNotifier with Provider package in TaskData class.
In this case you have to add notifyListener() inside getData() because it async task.

  Future<void> getData() async {
    final prefs = await SharedPreferences.getInstance();
    final String taskString = prefs.getString('task_data').toString();
    List<Task> tasksData = Task.decode(taskString);
    _tasks = tasksData;
    notifyListener(); // Add this line
  }

Answered By – Usama Karim

Answer Checked By – Marilyn (FlutterFixes Volunteer)

Leave a Reply

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