Persistent data storage in Ember with localStorage

Ember is a free and opensource javascript framework for single page applications. It follows model-view-view-model(MVVM) pattern.

Ember comes with an Ember CLI which can be used for creating and managing ember applications.

As you all know, there are a lot of UI frameworks available for building a single page application, and if you carefully watch you can see Ember in the top UI frameworks list.

Ember is not created and managed by any big corporation compared to react, angular etc. But, it has vast community support of very passionate developers.

Ember.js has a conventional project structure which makes it easy for developers to understand and write code in an organised manner. Ember has introduced a CLI to create, build, serve, and test Ember.js apps.

Ember is used in many popular websites like LinkedIn, Live Nation, Apple music etc. It is a framework for the web application, but it can be used to build both mobile and web applications. Apple music is an example of an ember desktop application.

In this article, I will explain to you how to set up an ember project and how to do simple CRUD operation using localStorage.

Ember CLI and Ember installation

Ember CLI is built with javascript, and it requires recent long term support(LTS) version of Node.js. Ember dependencies are downloaded use NPM which is available with Node.js.

You can check whether your machine has node and npmvia the following command.

node -version
npm -version

If you are getting “command not found” error message then install latest Node.js.

Ember CLI installation

npm install -g ember-cli
ember -v

Creating an Ember application

We can create a new ember web application using ember new command in ember-cli terminal.

ember new ember-crud-ls

The above command will create a new directory ember-crud-ls and set up an ember application with following inbuilt features,

  • A development server
  • ES6 features via Babel
  • Javascript and CSS minification capabilities
  • Auto build and compilation

we can quickly start the application from the ember-crud-ls directory using command ember-serve

The application will be available in the address http://localhost:4200/ with app/templates/application.hbs as the home page. If you edit this page, you can see page automatically load after compiling the new changes.

To build an application for adding, updating, deleting and showing a list of books, we should create a page first. In ember words, we can say like we should create a route. Routes mean a list of pages for an application.

Creating a Route (A page for your application)

For creating a route, we can use the command ember generate route followed by route name.

ember generate route books

Above command will create following files and changes,

  • A route js file fetching models or calling service for the page
  • A template to display items for the route
  • It makes an entry in the router.js file
  • Unit test file for the route
//app/routes/books.js
import Route from '@ember/routing/route';
export default Route.extend({
model() {
return ['The god of small things', 'Book of Ram', 'History of the world'];
}
});

Route template will be generated under app/templates

// app/templates/books.hbs
<h2>Books</h2>
<ul>
{{#each this.model as |book|}}
<li>{{book}}</li>
{{/each}}
</ul>

Creating an Ember UI component

A component will be presenting model data to a user, not fetching the model. Routes will fetch the model data.

We can easily create reusable elements using component. In ember, we can create a component using the command ember generate component followed by a component name.

ember generate component book-list

And we can call a component from route template like this.

{{book-list title=”Books” books=this.model}}

The dynamic title, books value will replace {{title}}, and {{book}} property in the component we pass from the route.

We can add code to list books in book-list component template file

app/templates/components/book-list.hbs
<h2>{{this.title}}</h2>
<ul>
{{#each this.books as |book|}}
<li>{{book}}</li>
{{/each}}
</ul>

Using Ember data for CRUD operation

Ember comes with a data management library ember-data store for managing data of your application.

Here’s the diagram of ember architecture.

source: ember guide

Ember data require model to manage data. Model is a class that represents properties and behavior of the data we used in our application. We can define models by extending DS.Model.

For adding a new model, we should create a file under the models folder. In our application for managing books, we need a book model. We can easily create a model using ember cli with the following command.

ember generate model book

It creates a file book.js under models folder. We can define the attribute needed for the book in this file.

import DS from ‘ember-data’;
export default DS.Model.extend({
name: DS.attr(‘string’),
author: DS.attr(‘string’),
});

Ember data store object is available in routes which can be used for managing records in the store. Ember data library provides following methods to manage records.

Creating Records

We can create a record using ember store.createRecord method. For creating a new book record we should pass type of record(book) and detail object in createRecord method.

store.createRecord(‘book’, {
name: ‘2 States’,
author: ‘Chetan bhagat’,
});

Updating records

We can make changes to the created records using the store.updateRecord method.

this.store.findRecord(‘book’, 1).then(function(book) {
book.set(‘name’, ‘Chetan Bhagat’);
});

Find record method will find the book record with id provided and we can update the record value.

Deleting Records

Destroying a record is easy using ember store.deleteRecord method.

store.findRecord(‘book’, 1).then(function(book) {
book.deleteRecord();
});

Fetching Records

Retrieve all records of a particular type by using store.findAll method

this.store.findAll(‘book’) .then(function(books) {
// Do something with ‘books’ list
});

we can read a single record using store.findRecord method,

this.store.findRecord(‘book’, 1).then(function(book) {
// Do something with ‘book’
});

Chrome has provided an add-on ember inspector for understanding and debugging ember apps. This add-on will helps you in development time. Here is the screenshot of book records created in our application.

Application Details— ember inspector screenshot

Persisting records in local storage

We can easily add, modify records in our application to using the above methods. But, those data will be lost if we refresh the browser. To persist in those data, we should save this data in a database.

Here I will explain to you how to store those data in browser localStorage. localStorage is widely used in web application for offline data storage purposes.

Majority browsers support localStorage for storing data. Here is the list of supported browser’s.

Browser support for localstorage

For persisting a record, we can use save() method on any instance of DS.Model. save() will make a network request to keep data. Ember-data will take care of the state of each record for you.

let book= store.createRecord(‘book’, {
name: ‘2 States’,
author: ‘Chetan Bhagat’,
});
book.save(); // => POST to ‘/books’

In ember-data, adapters determine how data is persisted in backend store. The backend URL, headers for communicating to rest API’s etc. can be added inside an adapter.js file.

For storing all data in local storage, we need local storage adapter. We can install already available npm module ember-local-storage for this purpose.

ember install ember-local-storage

Customizing adapter for application

We can generate an adapter for the application using the following command,

ember generate adapter application

Ember will generate a JSONAPIAdapter by default.

import DS from ‘ember-data’;
export default DS.JSONAPIAdapter.extend({
});

But, for this application, we are storing data in local storage. So we can replace the adapter.js code with following local storage adapter code.

export { default } from ‘ember-local-storage/adapters/local’;

Customizing serializer for application

In Ember, serializer format the data sent to and received from the backend database. We can create a serializer like below,

ember generate serializer application

Ember creates JSON API serializer by default.

import DS from ‘ember-data’;
export default DS.JSONAPISerializer.extend({
});

We can replace JSON API serializer with local storage serializer.

export { default } from ‘ember-local-storage/serializers/serializer’;

We can persist data with local storage with above serializer and adapter. We can see that data is persisting by refreshing the app URL after doing CRUD operations.

Conclusion

Hope you got some information about persisting data in local storage with ember.js.

For reference, check the code here: https://github.com/manubenjamin/ember-crud-ls

For an online demo, visit this URL: https://manubenjamin.github.io/ember-crud-ls/#/books

Please share your comments and queries.