Deprecations Added in Ember Data 2.x
What follows is a list of deprecations introduced to Ember Data during the 2.x cycle.
For more information on deprecations in Ember Data, see the main deprecations page.
Deprecations Added in 2.3
Non-primitive defaultValue for Model Attributes
Providing a non-primitive value as a defaultValue
has been deprecated because
the provided value is shared between all instances of the model. Using a
non-primitive value, such as defaultValue: []
, can lead to unexpected bugs when
that value is mutated.
If you wish to continue using a non-primitive value as the defaultValue
for an
attribute, you should provide a function that returns the value:
import DS from 'ember-data';
export default DS.Model.extend({
username: DS.attr('string'),
createdAt: DS.attr('date', {
defaultValue() {
return new Date();
}
})
});
RESTSerializer.keyForPolymorphicType
Previous versions of the
RESTSerializer
relied on
keyForAttribute
to determine the type key used for serializing polymorphic relationships. This
behavior has been deprecated in favor of using
keyForPolymorphicType
.
The benefit of having this additional hook is that you can customize the type
key separately from the key used for the relationship.
For example, given the following model:
import DS from 'ember-data';
export default DS.Model.extend({
commentable: belongsTo('commentable', { polymorphic: true }),
body: DS.attr('string')
});
When using the RESTSerializer
, Ember Data expects a payload that looks similar
the following:
{
"comment": {
"id": "1",
"commentable": "123",
"commentableType": "movie", // ${keyForAttribute}Type
"body": "I'll be back"
},
"movie": {
"id": "123",
"title": "The Terminator"
}
}
If your API instead responds with a key that doesn't follow the pattern of
${keyForAttribute}Type
:
{
"comment": {
"id": "1",
"commentable": "123",
"commentKind": "movie", // custom keyForPolymorphicType needed
"body": "I'll be back"
},
"movie": {
"id": "123",
"title": "The Terminator"
}
}
You can now override the keyForPolymorphicType
hook in your serializer to
accommodate:
import DS from 'ember-data';
export default DS.RESTSerializer.extend({
keyForPolymorphicType: function() {
return 'commentKind';
}
});
Deprecations Added in 2.6
RESTSerializer.normalizeHash
RESTSerializer.normalizeHash
has been deprecated in favor of using normalize
.
If you had this:
import DS from 'ember-data';
export default DS.RESTSerializer.extend({
normalizeHash: {
_id: function(hash) {
hash.id = hash._id;
delete hash._id;
return hash;
}
}
});
You could change it to this:
import DS from 'ember-data';
export default DS.RESTSerializer.extend({
normalize(model, hash, prop) {
if (prop === 'comments') {
hash.id = hash._id;
delete hash._id;
}
return this._super(...arguments);
}
});
Deprecations Added in 2.7
Date Prototype Extension
In previous versions of Ember Data, the native Date.parse
function was
replaced with Ember.Date.parse
, a progressive enhancement for ISO
8601 support in browsers that do not
support it (Safari 5-, IE 8-, Firefox 3.6-). Since these browser versions are no
longer supported by Ember or Ember data, this behavior has been deprecated.
To clear this deprecation, you should disable Ember Data's Date
prototype
extension.
With Ember >= v2.7.0, disable the prototype extension for Date
:
ENV = {
EmberENV: {
EXTEND_PROTOTYPES: {
Date: false
}
}
}
With Ember < v2.7.0, values must be provided for all prototype extensions:
var ENV = {
EmberENV: {
EXTEND_PROTOTYPES: {
Array: true,
Date: false,
Function: true,
String: true
}
}
};
If you're not sure which prototype extensions your app already has enabled, you
can check EmberENV.EXTEND_PROTOTYPES
in your browser's JavaScript console
while your app is running.
See Disabling Prototype Extensions for more information about how Ember uses prototype extensions.
Ember.Date.parse
Ember.Date.parse
was created as a progressive enhancement for ISO
8601 support in browsers that do not
support it (Safari 5-, IE 8-, Firefox 3.6-). These browsers versions are no
longer supported by Ember or Ember Data so Ember.Date.parse
has been
deprecated.
To clear this deprecation you should refactor your application's code to use
Date.parse
instead of Ember.Date.parse
.
Global version of DS
Using the global version of DS is deprecated. Import DS
or specific modules from ember-data
where needed.
For example, if you had:
/* globals DS */
It would be refactored to:
import DS from 'ember-data';
Store.queryRecord Array Response with RESTSerializer
When using
DS.RESTSerializer
with previous versions of Ember Data,
store.queryRecord
provided support for normalizing payloads containing an array of primary data.
This behavior has been deprecated because it is basically the same as using
store.query
and returning the first model.
Deprecated payload example with an array as the primary data:
// GET /users?username="GummyBear"
{
"users": [{
"id": "1",
"username": "GummyBear"
}]
}
Expected payload example with a single object as the primary data:
// GET /users?username="GummyBear"
{
"user": {
"id": "1",
"username": "GummyBear",
}
}
If you need to support an API that responds with an array as the primary data,
you have a few options. The simplest option is to use
store.query
instead of
store.queryRecord
:
this.store.query('user', { username: 'GummyBear' }).then((users) => {
return users.objectAt(0);
});
Another option is to override
normalizeQueryRecordResponse
in your serializer, manipulating the payload so it matches the expected format:
import DS from 'ember-data';
export default DS.RESTSerializer.extend({
normalizeQueryRecordResponse(store, primaryModelClass, payload) {
if (payload.users) {
payload.user = payload.users[0];
delete payload.users;
}
return this._super(...arguments);
}
});
Another option is to customize the URL of the request made by
store.queryRecord
so that it makes a request that returns the expected payload with a single
object as its primary data. This can be done by overriding
urlForQueryRecord
in your adapter:
import DS from 'ember-data';
export default DS.RESTAdapter.extend({
urlForQueryRecord() {
let baseURL = this.buildURL();
return `${baseURL}/user-query`;
}
});
Deprecations Added in 2.11
lookupAdapter
lookupAdapter
has been deprecated in favor of using adapterFor
.
lookupSerializer
lookupSerializer
has been deprecated in favor of using serializerFor
.
recordIsLoaded
recordIsLoaded
has been deprecated and is an alias for hasRecordForId
, which should be used instead.
If you have this:
store.recordIsLoaded('post', 1); // false
store.findRecord('post', 1).then(function() {
store.recordIsLoaded('post', 1); // true
});
You can change it to this:
store.hasRecordForId('post', 1); // false
store.findRecord('post', 1).then(function() {
store.hasRecordForId('post', 1); // true
});
When using
DS.RESTSerializer
with previous versions of Ember Data,
store.queryRecord
provided support for normalizing payloads containing an array of primary data.
This behavior has been deprecated because it is basically the same as using
store.query
and returning the first model.
Deprecated payload example with an array as the primary data:
// GET /users?username="GummyBear"
{
"users": [{
"id": "1",
"username": "GummyBear"
}]
}
Expected payload example with a single object as the primary data:
// GET /users?username="GummyBear"
{
"user": {
"id": "1",
"username": "GummyBear",
}
}
If you need to support an API that responds with an array as the primary data,
you have a few options. The simplest option is to use
store.query
instead of
store.queryRecord
:
this.store.query('user', { username: 'GummyBear' }).then((users) => {
return users.objectAt(0);
});
Another option is to override
normalizeQueryRecordResponse
in your serializer, manipulating the payload so it matches the expected format:
import DS from 'ember-data';
export default DS.RESTSerializer.extend({
normalizeQueryRecordResponse(store, primaryModelClass, payload) {
if (payload.users) {
payload.user = payload.users[0];
delete payload.users;
}
return this._super(...arguments);
}
});
Another option is to customize the URL of the request made by
store.queryRecord
so that it makes a request that returns the expected payload with a single
object as its primary data. This can be done by overriding
urlForQueryRecord
in your adapter:
import DS from 'ember-data';
export default DS.RESTAdapter.extend({
urlForQueryRecord() {
let baseURL = this.buildURL();
return `${baseURL}/user-query`;
}
});
Store.serialize
Store.serialize
has been deprecated in favor of
Model.serialize
as part of an effort to reduce duplication and API surface area.
Before:
let post = this.store.peekRecord('post', 123);
this.store.serialize(post);
After:
let post = this.store.peekRecord('post', 123);
post.serialize();
Deprecations Added in 2.12
JSONSerializer.shouldSerializeHasMany
The private method _shouldSerializeHasMany
has been promoted to the public
API. To remove this deprecation, please remove the underscore to use the public
shouldSerializeHasMany
method.
Deprecations Added in 2.13
Unused Initializers
The Ember Data initializers data-adapter
, injectStore
, transforms
, and store
are no longer used, so they are being removed.
Applications that depend on these for the ordering of their own custom initializers can substitute ember-data
instead, without any change in functionality.
Before:
export function initialize(application) {
// ... your code ...
};
export default {
name: 'websocketInit',
after: 'store',
initialize: initialize
};
After:
export function initialize(application) {
// ... your code ...
};
export default {
name: 'websocketInit',
after: 'ember-data',
initialize: initialize
};
Deprecations Added in Upcoming Features
BelongsToReference.push(DS.Model)
feature: ds-overhaul-references
Passing an instance of
DS.Model
to
BelongsToReference#push
has been deprecated. You should instead follow the
pattern of model.set('relationship', value)
to update a belongsTo
relationship with an instance of DS.Model
.
For example, if you have something like:
let post = this.store.peekRecord('post', 123);
let author = this.store.peekRecord('user', 456);
post.belongsTo('author').push(author);
You can remove this deprecation by refactoring your code to:
let post = this.store.peekRecord('post', 123);
let author = this.store.peekRecord('user', 456);
post.set('author', author);
HasManyReference.push(array)
feature: ds-overhaul-references
Deprecations Added in Pending Features
Passing an array to a HasManyReference#push
has been deprecated. You should
refactor your code to instead pass a JSON API Relationship
Object.
For example, if you previously had something like:
let commentsData = [
{ data: { type: 'comment', id: 1 } },
{ data: { type: 'comment', id: 2 } }
];
let post = this.store.peekRecord('post', 123);
post.hasMany('comments').push(commentsData);
You could remove this deprecation by refactoring your code to:
let commentsData = {
data: [
{ type: 'comment', id: 1 },
{ type: 'comment', id: 2 }
]
};
let post = this.store.peekRecord('post', 123);
post.hasMany('comments').push(commentsData);
HasManyReference.push Invalid Data
feature: ds-overhaul-references
In previous versions of Ember Data, HasManyReference#push
supported pushing
data that was almost formatted as a JSON API Relationship
Object, but
wasn't quite correct. Pushing data that is formatted this way has been
deprecated. You should refactor your code to instead push a properly formatted
JSON API Relationship Object.
For example, if you previously had something like:
let commentsData = {
data: [
{ data: { type: 'comment', id: 1 } },
{ data: { type: 'comment', id: 2 } }
]
};
let post = this.store.peekRecord('post', 123);
post.hasMany('comments').push(commentsData);
You could remove this deprecation by refactoring your code to:
let commentsData = {
data: [
{ type: 'comment', id: 1 },
{ type: 'comment', id: 2 }
]
};
let post = this.store.peekRecord('post', 123);
post.hasMany('comments').push(commentsData);
JSONAPISerializer.modelNameFromPayloadKey for Relationship
feature: ds-payload-type-hooks
Using JSONAPISerializer.modelNameFromPayloadKey
to normalize the type of a
relationship has been deprecated in favor of
JSONAPISerializer.modelNameFromPayloadType
.
See JSONAPISerializer.modelNameFromPayloadKey for Resource for more information.
JSONAPISerializer.modelNameFromPayloadKey for Resource
feature: ds-payload-type-hooks
Using JSONAPISerializer.modelNameFromPayloadKey
to normalize the type of a
resource has been deprecated in favor of
JSONAPISerializer.modelNameFromPayloadType
.
In the context of a JSON API payload, it is the value of the type
key that
maps to the name of the corresponding DS.Model
class rather than the key that
the data is nested under.
For example, if your API responds with a namespaced resource type in the payload
when you fetch a post
:
// GET /post/1
{
"data": {
"type": "api::v1::post",
"id": "1"
}
}
Previously, you would want to override modelNameFromPayloadKey
to remove the
namespace:
import DS from 'ember-data';
export default DS.JSONAPISerializer.extend({
payloadKeyFromModelName(modelName) {
return `api::v1::${modelName}`;
}
});
You can remove this deprecation by refactoring your serializer to instead use
payloadTypeFromModelName
:
import DS from 'ember-data';
export default DS.JSONAPISerializer.extend({
payloadTypeFromModelName(modelName) {
return `api::v1::${modelName}`;
}
});
JSONAPISerializer.payloadKeyFromModelName for belongsTo Relationship
feature: ds-payload-type-hooks
Using JSONAPISerializer.payloadKeyFromModelName
to serialize the type of a
belongsTo
relationship has been deprecated in favor of
JSONAPISerializer.payloadTypeFromModelName
.
See JSONAPISerializer.payloadKeyFromModelName for Resource for more information.
JSONAPISerializer.payloadKeyFromModelName for hasMany Relationship
feature: ds-payload-type-hooks
Using JSONAPISerializer.payloadKeyFromModelName
to serialize the type of a
hasMany
relationship has been deprecated in favor of
JSONAPISerializer.payloadTypeFromModelName
.
see jsonapiserializer.payloadkeyfrommodelname for Resource for more information.
JSONAPISerializer.payloadKeyFromModelName for Resource
feature: ds-payload-type-hooks
Using JSONAPISerializer.payloadKeyFromModelName
to serialize the type of a
model has been deprecated in favor of
JSONAPISerializer.payloadTypeFromModelName
.
For example, if your API expects a namespaced resource type in the payload that
is sent when you create a post
model:
// POST /api/posts/1
{
"data": {
"id": 1,
"type": "api::v1::post"
}
}
Previously, you would want to override payloadKeyFromModelName
to add the
namespace to the modelName
:
import DS from 'ember-data';
export default DS.JSONAPISerializer.extend({
payloadKeyFromModelName(modelName) {
return `api::v1::${modelName}`;
}
});
You can remove this deprecation by refactoring your serializer to instead use
payloadTypeFromModelName
:
import DS from 'ember-data';
export default DS.JSONAPISerializer.extend({
payloadTypeFromModelName(modelName) {
return `api::v1::${modelName}`;
}
});