Search code examples
flutterdartsharedpreferences

Flutter shared_preferences save list<any_class>


I tried to save a list to my shared preferences but the list isn't a String list it is a list of a special type class "todo". I tried it with ".cast<Todo>();", this worked with prefs.getStringList.... but dont work with prefs.setStringList. Here is a screenshot: Screenshot

When I try to do prefs.setStringList("shoppingCard", _todos); it says: "The argument type 'List' can't be assigned to the parameter type 'List'."

This is the source code of the class todo:

    class Todo {
  Todo({required this.name, required this.checked});
  final String name;
  bool checked;
}

class TodoItem extends StatelessWidget {
  TodoItem({
    required this.todo,
    required this.onTap,
  }) : super(key: ObjectKey(todo));

  final Todo todo;
  final Function onTap;

  TextStyle? _getTextStyle(bool checked) {
    if (!checked) return null;

    return const TextStyle(
      color: Colors.black54,
      decoration: TextDecoration.lineThrough,
    );
  }

  @override
  Widget build(BuildContext context) {
    return ListTile(
      onTap: () {
        onTap(todo);
      },
      leading: CircleAvatar(
        child: Text(todo.name[0]),
      ),
      title: Text(todo.name, style: _getTextStyle(todo.checked)),
    );
  }
}

Solution

  • If you need to save list of custom class you need convert it to string. First change your class model to this:

    class Todo {
      Todo({required this.name, required this.checked});
      final String name;
      bool checked;
      static Todo fromJson(Map<String, dynamic> json) {
        return Todo(name: json['name'], checked: json['checked']);
      }
    
      Map<String, dynamic> toJson() {
        return {
          'name': name,
          'checked': checked,
        };
      }
    }
    

    then for saving your list in SharedPreferences, try this:

    var prefs = await SharedPreferences.getInstance();
    prefs.setString('shoppingCard',
            jsonEncode({'data': _todos.map((e) => e.toJson()).toList()}));
    

    and for getting it, try this:

    var prefs = await SharedPreferences.getInstance();
    String? str = prefs.getString('shoppingCard');
        if (str != null) {
          var result = (jsonDecode(str) as Map)['data'] as List;
          result.map((e) => Todo.fromJson(e)).toList();
        }
    

    for example in you case, lets say we have list below:

    List<Todo> _todos = [
        Todo(checked: false, name: 'test1'),
        Todo(checked: true, name: 'test2')
      ];
    

    we add this list to SharedPreferences, like this:

    Future<void> _addTodoItem(String name) async {
        var prefs = await SharedPreferences.getInstance();
    
        prefs.setString('shoppingCard',
            jsonEncode({'data': _todos.map((e) => e.toJson()).toList()}));
        _textFieldController.clear();
      }
    

    and we get list from SharedPreferences, like this:

    Future<void> _getodoItem(String name) async {
        var prefs = await SharedPreferences.getInstance();
        var value = prefs.getString('shoppingCard');
        if (value != null) {
          var result = (jsonDecode(value) as Map)['data'] as List;
    
          setState(() {
            _todos = result.map((e) => Todo.fromJson(e)).toList();
          });
        }
      }