Store data as an object in shared preferences in flutter

Viewed 41626

I want to store an object in shared preferences which contains some fields in it like name, age, phone number etc. I don't know how to store an object in shared preferences in flutter.

7 Answers

You can Store an object in shared preferences as Below:

SharedPreferences shared_User = await SharedPreferences.getInstance();
Map decode_options = jsonDecode(jsonString);
String user = jsonEncode(User.fromJson(decode_options));
shared_User.setString('user', user);
            
SharedPreferences shared_User = await SharedPreferences.getInstance();
Map userMap = jsonDecode(shared_User.getString('user'));
var user = User.fromJson(userMap);
        
class User {
  final String name;
  final String age;
        
  User({this.name, this.age});
        
  factory User.fromJson(Map<String, dynamic> parsedJson) {
    return new User(
      name: parsedJson['name'] ?? "",
      age: parsedJson['age'] ?? "");
  }
        
  Map<String, dynamic> toJson() {
    return {
      "name": this.name,
      "age": this.age
    };
  }
}

After searching a lot of articles here you are

For Saving data, must be converted to JSON

 SharedPreferences prefs = await SharedPreferences.getInstance();

   Map<String, dynamic> user = 
    {'Usrname':'tom','Password':'pass@123'};

bool result = await prefs.setString('user', jsonEncode(user));

For Gettin data, must Deconverted from JSON

String userPref = prefs.getString('user');
     
Map<String,dynamic> userMap = jsonDecode(userPref) as Map<String, dynamic>;

To Save the object to Shared Preferences

SharedPreferences pref = await SharedPreferences.getInstance();
Map json = jsonDecode(jsonString);
String user = jsonEncode(UserModel.fromJson(json));
pref.setString('userData', user);

To Fetch the object from Shared Preferences

SharedPreferences pref = await SharedPreferences.getInstance();
Map json = jsonDecode(pref.getString('userData'));
var user = UserModel.fromJson(json);

You will need to import below mentioned packages

import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';

Easiest way to create Model Follow this answer -> https://stackoverflow.com/a/58708634/9236994

When Getting Data from the API and Saving it Into Sharepreference

 Future<UserDetails> UserInfo({String sesscode, regno}) async{
await Future.delayed(Duration(seconds: 1));
SharedPreferences preferences = await SharedPreferences.getInstance();
 var map = new Map<String, String>();
map["sesscode"] = sesscode;
map["regno"] = regno;

 var response = await http.post(Base_URL().user_info, body: map);
 Map decodedata = json.decode(response.body);
 if(decodedata != null){
  String user = jsonEncode(UserDetails.fromJson(decodedata));
  preferences.setString(SharePrefName.infoPref, user);
  return UserDetails.fromJson(decodedata);
}
  return null;
 }

I Create A function for Getting the Details You can call this function anywhere in your App

Future<UserDetails> getSavedInfo()async{
 SharedPreferences preferences = await SharedPreferences.getInstance();
 Map userMap = jsonDecode(preferences.getString(SharePrefName.infoPref));
  UserDetails user = UserDetails.fromJson(userMap);
  return user;
 }

Now, Am calling it inside a Class to get username

Future<UserDetails> usd = getSavedInfo();
       usd.then((value){
         print(value.surname);
       });

If you are getting you data from an API, what you initially get from an API endpoint is a String so you can store the data as a raw String and when you need it you can deserialize it and use where you want to use it

https://gist.github.com/k1ycee/33bb7e51dac81093f949bbd30d7d0dc9

Something like this, the drawback I feel is that if the JSON string data is much might not be advisable to store all the string rather deserialize it and take the ones you deem necessary.

SharePreferences Handler

I have created a LocalStorageRepository class, that is responsible to handle local data using SharedPreferences.

The class is dynamic and can work with any type of data (int, double, bool, String, and Object) using generics and JSON decoding and encoding.

In order to prevent pron errors, I added the LocalStorageKeys enum to handle the supported keys. Feel free to add more keys to that enum.

enum LocalStorageKeys { tutorialCompleted, user }

@singleton
class LocalStorageRepository {
  const LocalStorageRepository(SharedPreferences prefs) : _prefs = prefs;

  final SharedPreferences _prefs;

  bool keyExists(String key) => _prefs.containsKey(key);

  T? getValue<T>(
    LocalStorageKeys key, [
    T Function(Map<String, dynamic>)? fromJson,
  ]) {
    switch (T) {
      case int:
        return _prefs.getInt(key.name) as T?;
      case double:
        return _prefs.getDouble(key.name) as T?;
      case String:
        return _prefs.getString(key.name) as T?;
      case bool:
        return _prefs.getBool(key.name) as T?;
      default:
        assert(fromJson != null, 'fromJson must be provided for Object values');
        if (fromJson != null) {
          final stringObject = _prefs.getString(key.name);
          if (stringObject == null) return null;
          final jsonObject = jsonDecode(stringObject) as Map<String, dynamic>;
          return fromJson(jsonObject);
        }
    }
    return null;
  }

  void setValue<T>(LocalStorageKeys key, T value) {
    switch (T) {
      case int:
        _prefs.setInt(key.name, value as int);
        break;
      case double:
        _prefs.setDouble(key.name, value as double);
        break;
      case String:
        _prefs.setString(key.name, value as String);
        break;
      case bool:
        _prefs.setBool(key.name, value as bool);
        break;
      default:
        assert(
          value is Map<String, dynamic>,
          'value must be int, double, String, bool or Map<String, dynamic>',
        );
        final stringObject = jsonEncode(value);
        _prefs.setString(key.name, stringObject);
    }
  }
}

In case you want to get an Object value from LocalStorageRepository, you will need to provide its fromJson decoder.

final user = _localStorage.getValue(LocalStorageKeys.user, User.fromJson);

Hope that hence example will help others out there.

Feel free to edit this question and suggest any changes.

Related