45

I have a list of favorite music, which I retrieve from music when the app is opened for the first time, the app gets a favorite music list from favorite. I want to save this list to shared

preferences.List<Music> favoriteMusic = new List<Music>();

where music class is:

class Music {
  final int id;
  final String name, size, rating, duration, img;
  bool favorite;

  Music({
    this.id,
    this.rating,
    this.size,
    this.duration,
    this.name,
    this.img,
    this.favorite,
  });

  factory Music.fromJson(Map<String, dynamic> jsonData){
    return Music(
      id: jsonData['id'],
      rating: jsonData['rating'],
      size: jsonData['size'],
      duration: jsonData['duration'],
      name: jsonData['name'],
      img: jsonData['img'],
      favorite: false,
    );
  }
}

How can I save favorite music list?

Hamed
  • 5,867
  • 4
  • 32
  • 56
sumseflut
  • 628
  • 1
  • 7
  • 9

6 Answers6

92

You should do these steps

to save the object:

  1. convert your object to map with toMap() method
  2. encode your map to string with encode(...) method
  3. save the string to shared preferences

for restoring your object:

  1. decode shared preference string to a map with decode(...) method
  2. use fromJson() method to get your object

UPDATE FULL SAMPLE

import 'dart:convert';

void main() async {
  final SharedPreferences prefs = await SharedPreferences.getInstance();
  
  // Encode and store data in SharedPreferences
  final String encodedData = Music.encode([
    Music(id: 1, ...),
    Music(id: 2, ...),
    Music(id: 3, ...),
  ]);

  await prefs.setString('musics_key', encodedData);

  // Fetch and decode data
  final String musicsString = await prefs.getString('musics_key');

  final List<Music> musics = Music.decode(musicsString);
}

class Music {
  final int id;
  final String name, size, rating, duration, img;
  bool favorite;

  Music({
    this.id,
    this.rating,
    this.size,
    this.duration,
    this.name,
    this.img,
    this.favorite,
  });

  factory Music.fromJson(Map<String, dynamic> jsonData) {
    return Music(
      id: jsonData['id'],
      rating: jsonData['rating'],
      size: jsonData['size'],
      duration: jsonData['duration'],
      name: jsonData['name'],
      img: jsonData['img'],
      favorite: false,
    );
  }

  static Map<String, dynamic> toMap(Music music) => {
        'id': music.id,
        'rating': music.rating,
        'size': music.size,
        'duration': music.duration,
        'name': music.name,
        'img': music.img,
        'favorite': music.favorite,
      };

  static String encode(List<Music> musics) => json.encode(
        musics
            .map<Map<String, dynamic>>((music) => Music.toMap(music))
            .toList(),
      );

  static List<Music> decode(String musics) =>
      (json.decode(musics) as List<dynamic>)
          .map<Music>((item) => Music.fromJson(item))
          .toList();
}
Hamed
  • 5,867
  • 4
  • 32
  • 56
  • is this method only for 1 object? – sumseflut Apr 21 '20 at 08:45
  • you can easily expand it for a list of objects. you just need to create a List of Maps. – Hamed Apr 21 '20 at 10:53
  • 3
    this actually solved my problem to save List of Object, however it only works if that object has primitive data type as its variables. In my case MyObject has a List in it as a variable. Any solution? Thanks – David B. Nov 30 '20 at 15:13
  • Hi, can anybody give me an example of storing List of objects in shared preferences. appending new objects to the current shared preferences and removing from it? – Ameena Shafeer Mar 25 '21 at 06:43
  • check out these two links to understand what is going on to adapt his solution to more complex or simpler objects/classes: https://bezkoder.com/dart-flutter-parse-json-string-array-to-object-list/ https://bezkoder.com/dart-flutter-convert-object-to-json-string/ – jayesh saha May 25 '21 at 10:32
  • The documentation for SharedPreferences state, " Data may be persisted to disk asynchronously, and there is no guarantee that writes will be persisted to disk after returning, so this plugin must not be used for storing critical data." What is critical data in this statement? Does the music example in the question qualify as critical data? – mLstudent33 Sep 13 '21 at 00:03
  • Also flutter.dev shows `Future` for await, not `final`: https://pub.dev/packages/shared_preferences/example – mLstudent33 Sep 13 '21 at 00:14
8

Flutter's shared_preferences plugin has a method: setStringList(String key, List<String> value), so you can just write serializer for your objects.

Michał Dobi Dobrzański
  • 1,449
  • 1
  • 20
  • 19
  • 1
    Thanks. Could please you give an example of how to retrieve data that is stored this way? – sj_959 Dec 18 '21 at 14:13
5

Convert it to a string, you can store it

import 'dart:convert';
...
var s = json.encode(myList);
// or var s = jsonEncode(myList);

json.decode() //convert a string to List when you load it
Rudresh Narwal
  • 2,740
  • 3
  • 11
  • 21
  • 1
    if i want to convert string into list then how i can do it. split is not good method because i get reponse of list and then save in shared pref as a string then get new screen this pref but cant convert back to list – Adnan haider Aug 04 '21 at 11:13
3

For noob folks like me who want to understand a bit more about the magic our dear friend Hamed did in his answer, or want to adapt his solution to more complex classes with lists/other classes, check out these two links: https://bezkoder.com/dart-flutter-parse-json-string-array-to-object-list/

https://bezkoder.com/dart-flutter-convert-object-to-json-string/

jsonEncode() and jsonDecode() are the same as json.encode() and json.decode()

jayesh saha
  • 351
  • 3
  • 7
2

simply use stringlist in shared preferences

basic syntax:

    // read
    final myStringList = prefs.getStringList('my_string_list_key') ?? [];
    // write
    prefs.setStringList('my_string_list_key', ['a', 'b', 'c']);

Firstly convert the object to a map. Then convert the map to a JSON string using jsonEncode and at the end save the JSON string to shared preferences

Sample example:

        // import 'dart:convert';
    Person person = Person('Mary', 30);
    Map<String, dynamic> map = {
      'name': person.name,
      'age': person.age
    };
    String rawJson = jsonEncode(map);
    prefs.setString('my_string_key', rawJson);

 

retrieve data

final rawJson = prefs.getString('my_string_key') ?? '';
Map<String, dynamic> map = jsonDecode(rawJson);
final person = Person(map['name'], map['age']);
Community
  • 1
  • 1
Tarun Jain
  • 411
  • 5
  • 17
0

Here the solution for store and retrieve some list of object data to shared preference from api response

Here the sampleData carrying whole data from api and sampleList is the list to store shared preference

    SampleModel sampleData = await ApiCall();
    List<SampleDataItem> sampleList = sampleData.sampleList;

    //Convert sampleList to string
    String sampleStringList = jsonEncode(sampleList);
    
    print(sampleStringList);

    // Store to preference as string 
    PreferenceUtils.setSampleListData(sampleStringList);

Here the reverse that shared preference string data to object list model

    // get data from preference
String sampleDataFromPref = PreferenceUtils.getSampleListData();

// convert string data to jsonMap
var sampleJsonMap = json.decode(sampleDataFromPref);

// convert json map list to object model lis
List<SampleDataItem> sampleListFromPreferance = List<SampleDataItem>.from(jsonMap.map((x) => SampleDataItem.fromJson(x)));

// print the final output
print(sampleListFromPreferance);
Rahul Raj
  • 1,010
  • 9
  • 10