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.DShas 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
Recordclass is for individual in-memory records that correspond to say, a row in your database. - The
Mapperclass encapsulates the ORM's CRUD logic. An instance ofMappercorresponds to say, a table in your database. - The
Containerclass provides a convenient way to define and manageMapperinstances. Use this instead of managingMapperinstances manually. - The
DataStoreandSimpleStoreclasses extendContainer, and implement an in-memory Identity Map for cachingRecordinstances. - The
Schemaclass 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
extendmethod that you can use).
- Added
- The official v3 recommendation is that
DataStorebe used in the browser andContainerbe used in Node.js (DataStoreadds 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 settracktotrue. Passive change detection viaRecord#hasChanges,Record#changes, andRecord#previousworks 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,LinkedCollectionandQuery. 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 almost 9 years ago
