Migrating to v3
Migration path to JSData 3.0.0
Attention
While JSData v3 tried to stay API-compatible with v2, it is a completely new codebase. This migration guide may be incomplete. If you think anything in this guide is incorrect or missing, please add it (via the Suggest Edits button) or open an issue.
See the CHANGELOG for a detailed list of changes.
When upgrading to JSData 3.0 be aware of the following:
JSData requires the presence of a Promise
constructor in the global environment. In the browser, window.Promise
must be available. In Node.js, global.Promise
must be available. Here is a handy library for polyfilling: https://github.com/jakearchibald/es6-promise. Please check caniuse.com for browser Promise compatibility. Please check node.green for Node.js Promise compatibility.
JSData also requires full ES5 support from the runtime. Here is a handy library for polyfilling: https://github.com/afarkas/html5shiv. Please check kangax.github.io for browser ES5 compatibility. All supported versions of Node.js have full ES5 compatibility.
JSData has been completely re-architected for better flexibility and to allow you to compose and customize according to your needs.
Breaking changes
JSData.DS
has been split into a number of different components with more focused responsibilities, so you can flexibly construct your app's data layer.- Added
DataStore
,SimpleStore
,Container
,Mapper
,Record
,Schema
, and several others. - The
Record
class is for individual in-memory records that correspond to say, a row in your database. - The
Mapper
class encapsulates the ORM's CRUD logic. An instance ofMapper
corresponds to say, a table in your database. - The
Container
class provides a convenient way to define and manageMapper
instances. Use this instead of managingMapper
instances manually. - The
DataStore
andSimpleStore
classes extendContainer
, and implement an in-memory Identity Map for cachingRecord
instances. - The
Schema
class helps implement validation and change detection. - Each class is "just a function", so you can extend them using ES5-style inheritance or ES6 class syntax (they also have a Backbone-style
extend
method that you can use).
- Added
- The official v3 recommendation is that
DataStore
be used in the browser andContainer
be used in Node.js (DataStore
adds a bunch of functionality that's generally not used on the server). - Use of
Object.observe
(and observe-js) has been dropped. Change detection has been re-implemented Backbone-style. Active change detection requires that you define a schema and settrack
totrue
. Passive change detection viaRecord#hasChanges
,Record#changes
, andRecord#previous
works without having to explicitly enable it. - All "reap" and expiration functionality has been removed. However, the increased flexibility of v3 allows you to easily add your own cache-busting expiration schemes.
Backwards compatible changes
- Added support secondary indexes (via Mindex) on the in-memory collections that hold record instances. Allows for really fast querying on in-memory records.
- Other classes that were added (not mentioned above) are
Component
,Settable
,Collection
,LinkedCollection
andQuery
. You likely won't use them directly unless you're composing custom components or implementing plugins and derivative libraries.
Summary of usage differences
Attention
There may be differences not covered here. Consult the v3 API Reference Docs for detailed API reference of the new JSData components.
Create a store in the browser:
Before | After |
---|---|
const store = new DS(); | const store = new DataStore(); |
Create a store in Node.js (while you can use DataStore
on the server, you're better off using Container
):
Before | After |
---|---|
const store = new DS(); | const store = new Container(); |
Define a Model or Resource:
Before | After |
---|---|
store.defineResource({ name: 'foo', // options go here }); | store.defineMapper('foo', { // options go here }); |
Use custom class for records:
Before | After |
---|---|
function CustomRecord () {} store.defineResource({ name: 'foo', useClass: CustomRecord }); | const CustomRecord = Record.extend(); store.defineMapper('foo', { recordClass: CustomRecord }); or class CustomRecord extends Record {} store.defineMapper('foo', { recordClass: CustomRecord }); |
Computed properties:
Before | After |
---|---|
store.defineResource({ name: 'user', computed: { fullName: ['first', 'last', function (first, last) { return first + ' ' + last; }] } }); | See example - Open in Plnkr |
Record saves/creates itself:
Before | After |
---|---|
const userRecord = store.createInstance('user', { name: 'John' }); userRecord.DSCreate().then(...); | const userRecord = store.createRecord('user', { name: 'John' }); userRecord.save().then(...); |
Record saves/updates itself:
Before | After |
---|---|
record.DSUpdate({ key: 'value' }).then(...); | record.set({ key: 'value' }).save().then(...); or record.key = value; record.save().then(...); |
Record destroys itself:
Before | After |
---|---|
record.DSDestroy().then(...); | record.destroy().then(...); |
HTTP actions:
store.defineResource({ name: 'user', actions: { count: { method: 'POST' } } }); | See example - Open in Plnkr |
Change detection:
Before | After |
---|---|
In Angular, you might do:$scope.$watch(() => DS.lastModified('lesson', 1234), () => { $scope.lesson = DS.get('lesson', 1234); }); In React, you might list for the DS.change event to trigger component re-renders. | See Tracking changes. |
Validation:
Before | After |
---|---|
See v2 validation | See Tutorial Step 6: Schemas & Validation. |
Relations:
Before | After |
---|---|
See v2 relations. | See Tutorial Step 7: Relations. |
Updated over 7 years ago