0
class Restaurant {
  Restaurant({
    required this.name,
    required this.description,
    required this.address,
    required this.imageUrl,
  });

  Restaurant.fromJson(Map<String, Object?> json)
      : this(
          name: json['name']! as String,
          description: json['description']! as String,
          address: json['address']! as String,
          imageUrl: json['imageUrl'] as String,
        );

  final String name;
  final String description;
  final String address;
  final String imageUrl;

  Map<String, Object?> toJson() {
    return {
      'name': name,
      'description': description,
      'address': address,
      'imageUrl': imageUrl,
    };
  }
}

I get the list of restaurants from Firebase and when the user clicks Favorite Icon, I want to save that restaurant locally and retrieve the list of favorite restaurants and show it on another page. I know I can do it on Firebase directly but for now, I want it saved locally.

I am looking forward to hearing from all of you. Thank you.

peakystewie
  • 141
  • 2
  • 17
  • Another option is to save and read JSON strings in the `SharedPreferences`. Then you can use `toJson` and `fromJson` for further processing. – Roslan Amir Feb 08 '22 at 11:08

2 Answers2

1

Like this

List<Restaurant> restaturants = [Restuarant(...),Restuarant(...)];
List<String> encodedRestaturants = restaturants.map((res)=>json.encode(res.toJson())).toList();

//to write
prefs.setStringList("restaturants",encodedRestaturants);

//to read
List<String> decodedRestaturantsString = prefs.getStringList("restaturants");
List<Restaurant> decodedRestaturants = decodedRestaturantsString.map((res)=>Restaturant.fromJson(json.decode(res))).toList();

Sahil Hariyani
  • 1,078
  • 3
  • 11
  • Generally, it seems to work, but when I try to add more than one restaurant as a favorite, it seems the last one removes the first, and the list always contains only one restaurant. Normally, it should expand based on how many restaurants I select as favorites. Any idea why it's happening? – – peakystewie Feb 08 '22 at 12:03
  • Can you add the code to the question? – Sahil Hariyani Feb 08 '22 at 12:12
  • No problem, I found out where the problem was. Now the only thing I want to figure out is when a restaurant is in favorites, and users deselect it, how can I remove that specific restaurant from the shared preferences list? – peakystewie Feb 08 '22 at 12:14
  • //For removing specific item from a list with the attribute value restaturants.removeWhere((res) => res.id == '001') – Sahil Hariyani Feb 08 '22 at 12:22
  • just rewrite shared preference list after the remove operation using prefs.setStringList – Sahil Hariyani Feb 08 '22 at 12:24
  • Thanks, everything works and your explanation was clear! And one last thing, I store the bool isFavorite inside my object and this object is stored inside the Shared Preference list. I need to check this value, so if it is true then put a condition and run the remove() function when the button is clicked, else run the store() function. How can I access that value? – peakystewie Feb 08 '22 at 13:36
1

Instead using SharedPreferences setStringList, you can use setString.

Here excerpt using setStringList:

 // sample restaurants.
 List<Restaurant> favoriteRestos = [resto1, resto2, resto3];

 List<String> favorites = [];

 // Generate json for each restaurant
 for(var resto in favoriteRestos) {
    var json = jsonEncode(resto);
    favorites.add(json);
 }

// Obtain shared preferences.
final prefs = await SharedPreferences.getInstance();

// saving
await prefs.setStringList('favorites', favorites);

// Reading part
List<String> jsonRestos = prefs.getStringList('favorites')??[];

List<Restaurant> resFavorites = [];
for(var jsonResto in jsonRestos) {
   var map = jsonDecode(jsonResto);
   var resto = Restaurant.fromJson(map);
   resFavorites.add(resto);
}

For setString:

List<Restaurant> favoriteRestos = [resto1, resto2, resto3];
var json = jsonEncode(favoriteRestos);

// Obtain shared preferences.
final prefs = await SharedPreferences.getInstance();

// saving
await prefs.setString('favorites', json);

// reading
var resJson = prefs.getString('favorites')??'';
var parsedJson = jsonDecode(resJson);
List<Restaurant> items = List<Restaurant>.from(parsedJson.map((i) => Restaurant.fromJson(i)));

Note: You need to update your Restaurant class. See https://docs.flutter.dev/development/data-and-backend/json#serializing-json-inside-model-classes

ישו אוהב אותך
  • 28,609
  • 11
  • 78
  • 96
  • Generally, it seems to work, but when I try to add more than one restaurant as a favorite, it seems the last one removes the first, and the list always contains only one restaurant. Normally, it should expand based on how many restaurants I select as favorites. Any idea why its happening? – peakystewie Feb 08 '22 at 11:55
  • you need to read the previous favorites to temporary list, then add the new favorite to it. Then, save the list. – ישו אוהב אותך Feb 08 '22 at 12:55