Persisting data with Ember Data

Ember Data is Ember's data-access mechanism. It provides a simple API to deal with data, abstracting the complexities and protocols of data access and diverse data sources. With Ember Data, clients can deal with data models just as any other Ember object.

Ember Data defines a set of fundamental components that handle various roles and responsibilities in data access. These components are grouped under the namespace DS. The following table describes the most important Ember Data components defined under DS:

Component

Purpose

DS.Model

This is the fundamental unit of data and represents a record in a data collection. You need to define your data models by extending this class. It provides methods to save, delete, reload, and iterate properties, relationships, related types, and so on. It provides information about states, attributes, fields, relationships, errors, and so on. Also, it provides life cycle hook events.

DS.Store

This is the local repository of all the data created, fetched, and modified by Ember Data. Store fetches data with the help of adapters and converts them into appropriate DS.Model instances. Using serializers, Store serializes model instances into forms suitable for the servers. It provides methods for querying and creating new records.

DS.Adapter

This is an abstract implementation that receives various persistence commands from Store and translates them into forms that the actual data source (such as a Server API or a browser local storage) understands. Ember ships two concrete implementations: DS.RESTAdapter and DS.JSONAPIAdapter. Override the adapters if you want to change the default behaviors or attributes, such as remote URLs and headers.

DS.Serializer

This normalizes DS.Model instances into payloads for the API (or whichever data source it is) and serializes them back into the model. Two default serializers are RestSerializer and JSONAPISerializer. Override the serializers to customize the data formats for the server.

Ember Data architecture

Ember Data components communicate with each other asynchronously for data access operations, based on a promise. The query and find methods of both the Store and Adapter are asynchronous, and essentially return a promise object immediately. Once resolved, the model instance is created and returned to the client. The following diagram demonstrates how Ember Data components coordinate a find method operation asynchronously:

Ember Data architecture

The clients of Ember Data components, which are typically routes, components, controllers, services, and so on, do not directly deal with adapters and serializers. They talk to the Store and model for normal data-access operations. Since the Route.model method (hook) supports promise objects, the transition will pause until the promise is resolved. We do not deal with resolving promises and hence with asynchronicity; rather, Ember handles it smartly.

Defining models

Models represent the domain data of an Ember application. They need to be defined in proper structures and registered with the store before they can be used for data access. An Ember CLI project expects models under the app/models/ directory, or app/<pod-dir>/models/ in case you are using the POD directory structure.

Let's see a sample model definition. The following is the definition of a user model:

import DS from 'ember-data';

export default DS.Model.extend({

  name: DS.attr('string'),
  userName: DS.attr('string'),
  password: DS.attr('string'),
  dateOfBirth: DS.attr('date'),
  profileImage: DS.belongsTo('file')
});

Model attributes can be of the string, number, Boolean, and date types by default. For custom types, you need to subclass DS.Transform. Attributes can have default values too. You can specify default values as shown in the following line:

dateOfBirth: DS.attr('date', { defaultValue: new Date() }),

Defining model relationships

Models can engage in one-to-one, one-to-many, and many-to-many relationships among themselves:

  • A one-to-one relationship is defined using DS.belongsTo in both model definitions
  • A one-to-many relationship is defined using DS.belongsTo in one model and DS.hasMany in the other model
  • A many-to-many relationship is declared when both models have DS.hasMany defined for each other
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset