Flutter: Want to save data in local storage? Without Shared Preferences

October 06, 2018
Flutter is a new mobile developing framework, but it's growing fast and become favorite of many developers because it's easy to learn and good performance (this is the best mobile development yet for me). If you want to add data in local storage, there is a plugin for fo it, it's called Shared Preferences. The plugin is an asynchronous function.

The shared preferences plugin is good by the way, it's not bad at all, but because it's running as async, you can't get the data immediately, it will check the data while the task is still moving to the other task and will bring you the data after the checking was finished. Sometimes we need it, but sometimes we want it "right now" if it's available and don't running other task if it's not. The new plugin coming in late September 2018 called localstorage solved this problem because it's not running as async.

Localstorage plugin official package for dart language
If you want to know the detail about this package, you can check to this link or this github link

Installation

Add dependency to pubspec.yaml
dependencies:
  ...
  localstorage: ^1.0.0
Run in your terminal
flutter packages get

Import the package in your page (widget)
import 'package:localstorage/localstorage.dart';

declare the global variable of local storage function inside your page state widget.
final LocalStorage storage = new LocalStorage('todo_app');

save data to local storage by using setItem function
storage.setItem('todos', list.toJSONEncodable());

get data from local storage by using getItem function
var items = storage.getItem('todos');


A full example of this implementation
example/lib/main.dart
import 'package:flutter/material.dart';

import 'package:localstorage/localstorage.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Localstorage Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  HomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class TodoItem {
  String title;
  bool done;

  TodoItem({this.title, this.done});

  toJSONEncodable() {
    Map<String, dynamic> m = new Map();

    m['title'] = title;
    m['done'] = done;

    return m;
  }
}

class TodoList {
  List<TodoItem> items;

  TodoList() {
    items = new List();
  }

  toJSONEncodable() {
    return items.map((item) {
      return item.toJSONEncodable();
    }).toList();
  }
}

class _MyHomePageState extends State<HomePage> {
  final TodoList list = new TodoList();
  final LocalStorage storage = new LocalStorage('todo_app');
  bool initialized = false;
  TextEditingController controller = new TextEditingController();

  _toggleItem(TodoItem item) {
    setState(() {
      item.done = !item.done;
      _saveToStorage();
    });
  }

  _addItem(String title) {
    setState(() {
      final item = new TodoItem(title: title, done: false);
      list.items.add(item);
      _saveToStorage();
    });
  }

  _saveToStorage() {
    storage.setItem('todos', list.toJSONEncodable());
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Localstorage demo'),
      ),
      body: Container(
          padding: EdgeInsets.all(10.0),
          constraints: BoxConstraints.expand(),
          child: FutureBuilder(
            future: storage.ready,
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              if (snapshot.data == null) {
                return Center(
                  child: CircularProgressIndicator(),
                );
              }

              if (!initialized) {
                var items = storage.getItem('todos');

                if (items != null) {
                  (items as List).forEach((item) {
                    final todoItem =
                        new TodoItem(title: item['title'], done: item['done']);
                    list.items.add(todoItem);
                  });
                }

                initialized = true;
              }

              List<Widget> widgets = list.items.map((item) {
                return CheckboxListTile(
                  value: item.done,
                  title: Text(item.title),
                  selected: item.done,
                  onChanged: (bool selected) {
                    _toggleItem(item);
                  },
                );
              }).toList();

              return Column(
                children: <Widget>[
                  Expanded(
                    flex: 1,
                    child: ListView(
                      children: widgets,
                      itemExtent: 50.0,
                    ),
                  ),
                  TextField(
                    controller: controller,
                    decoration: InputDecoration(
                      labelText: 'What to do?',
                    ),
                    onEditingComplete: () {
                      _addItem(controller.value.text);
                      controller.clear();
                    },
                  ),
                ],
              );
            },
          )),
    );
  }
}


2 comments:

Powered by Blogger.