Skip to content

Documentation / @ember-data/serializer / json-api / default

Defined in: packages/serializer/src/json-api.js:132

⚠️ This is LEGACY documentation for a feature that is no longer encouraged to be used. If starting a new app or thinking of implementing a new adapter, consider writing a Handler instead to be used with the RequestManager

In EmberData a Serializer is used to serialize and deserialize records when they are transferred in and out of an external source. This process involves normalizing property names, transforming attribute values and serializing relationships.

JSONAPISerializer supports the http://jsonapi.org/ spec and is the serializer recommended by Ember Data.

This serializer normalizes a JSON API payload that looks like:

app/models/player.js
js
import Model, { attr, belongsTo } from '@ember-data/model';

export default class Player extends Model {
  @attr('string') name;
  @attr('string') skill;
  @attr('number') gamesPlayed;
  @belongsTo('club') club;
}
app/models/club.js
js
import Model, { attr, hasMany } from '@ember-data/model';

export default class Club extends Model {
  @attr('string') name;
  @attr('string') location;
  @hasMany('player') players;
}
js
  {
    "data": [
      {
        "attributes": {
          "name": "Benfica",
          "location": "Portugal"
        },
        "id": "1",
        "relationships": {
          "players": {
            "data": [
              {
                "id": "3",
                "type": "players"
              }
            ]
          }
        },
        "type": "clubs"
      }
    ],
    "included": [
      {
        "attributes": {
          "name": "Eusebio Silva Ferreira",
          "skill": "Rocket shot",
          "games-played": 431
        },
        "id": "3",
        "relationships": {
          "club": {
            "data": {
              "id": "1",
              "type": "clubs"
            }
          }
        },
        "type": "players"
      }
    ]
  }

to the format that the Ember Data store expects.

Customizing meta

Since a JSON API Document can have meta defined in multiple locations you can use the specific serializer hooks if you need to customize the meta.

One scenario would be to camelCase the meta keys of your payload. The example below shows how this could be done using normalizeArrayResponse and extractRelationship.

app/serializers/application.js
js
import JSONAPISerializer from '@ember-data/serializer/json-api';

export default class ApplicationSerializer extends JSONAPISerializer {
  normalizeArrayResponse(store, primaryModelClass, payload, id, requestType) {
    let normalizedDocument = super.normalizeArrayResponse(...arguments);

    // Customize document meta
    normalizedDocument.meta = camelCaseKeys(normalizedDocument.meta);

    return normalizedDocument;
  }

  extractRelationship(relationshipHash) {
    let normalizedRelationship = super.extractRelationship(...arguments);

    // Customize relationship meta
    normalizedRelationship.meta = camelCaseKeys(normalizedRelationship.meta);

    return normalizedRelationship;
  }
}

Since

1.13.0 JSONAPISerializer

Constructors

Constructor

ts
new default(owner?): default;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:8

Parameters

owner?

Owner

Returns

default

Properties

concatenatedProperties?

ts
optional concatenatedProperties: string | string[];

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:655


mergedProperties?

ts
optional mergedProperties: unknown[];

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:656


store

ts
store: default;

Defined in: packages/serializer/src/index.ts:141


_lazyInjections()?

ts
readonly static optional _lazyInjections: () => void;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:654

Returns

void


_onLookup()?

ts
readonly static optional _onLookup: (debugContainerKey) => void;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:653

Parameters

debugContainerKey

string

Returns

void


[INIT_FACTORY]?

ts
readonly static optional [INIT_FACTORY]: null;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/mixin.d.ts:116


isClass

ts
readonly static isClass: boolean;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:651


isMethod

ts
readonly static isMethod: boolean;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:652


mergedProperties

ts
readonly static mergedProperties: Object;

Defined in: packages/serializer/src/json.js:182

The attrs object can be used to declare a simple mapping between property names on Model records and payload keys in the serialized JSON object representing the record. An object with the property key can also be used to designate the attribute's key on the response payload.

Example

app/models/person.js
js
import Model, { attr } from '@ember-data/model';

export default class PersonModel extends Model {
  @attr('string') firstName;
  @attr('string') lastName;
  @attr('string') occupation;
  @attr('boolean') admin;
}
app/serializers/person.js
js
import JSONSerializer from '@ember-data/serializer/json';

export default class PersonSerializer extends JSONSerializer {
  attrs = {
    admin: 'is_admin',
    occupation: { key: 'career' }
  }
}

You can also remove attributes and relationships by setting the serialize key to false in your mapping object.

Example

app/serializers/person.js
js
import JSONSerializer from '@ember-data/serializer/json';

export default class PostSerializer extends JSONSerializer {
  attrs = {
    admin: { serialize: false },
    occupation: { key: 'career' }
  }
}

When serialized:

javascript
{
  "firstName": "Harry",
  "lastName": "Houdini",
  "career": "magician"
}

Note that the admin is now not included in the payload.

Setting serialize to true enforces serialization for hasMany relationships even if it's neither a many-to-many nor many-to-none relationship.


primaryKey

ts
readonly static primaryKey: string = 'id';

Defined in: packages/serializer/src/json.js:113

The primaryKey is used when serializing and deserializing data. Ember Data always uses the id property to store the id of the record. The external source may not always follow this convention. In these cases it is useful to override the primaryKey property to match the primaryKey of your external store.

Example

app/serializers/application.js
js
import JSONSerializer from '@ember-data/serializer/json';

export default class ApplicationSerializer extends JSONSerializer {
  primaryKey = '_id'
}

Default

ts
'id'

PrototypeMixin

ts
static PrototypeMixin: any;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:647


superclass

ts
static superclass: any;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:648

Accessors

_debugContainerKey

Get Signature

ts
get _debugContainerKey(): false | `${string}:${string}`;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/index.d.ts:34

Returns

false | `${string}:${string}`


isDestroyed

Get Signature

ts
get isDestroyed(): boolean;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:272

Destroyed object property flag.

if this property is true the observers and bindings were already removed by the effect of calling the destroy() method.

Default
ts
false
@public
Returns

boolean

Set Signature

ts
set isDestroyed(_value): void;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:273

Parameters
_value

boolean

Returns

void


isDestroying

Get Signature

ts
get isDestroying(): boolean;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:284

Destruction scheduled flag. The destroy() method has been called.

The object stays intact until the end of the run loop at which point the isDestroyed flag is set.

Default
ts
false
@public
Returns

boolean

Set Signature

ts
set isDestroying(_value): void;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:285

Parameters
_value

boolean

Returns

void

Methods

addObserver()

Call Signature

ts
addObserver<Target>(
   key, 
   target, 
   method): this;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/observable.d.ts:333

Adds an observer on a property.

This is the core method used to register an observer for a property.

Once you call this method, any time the key's value is set, your observer will be notified. Note that the observers are triggered any time the value is set, regardless of whether it has actually changed. Your observer should be prepared to handle that.

There are two common invocation patterns for .addObserver():

  • Passing two arguments:
    • the name of the property to observe (as a string)
    • the function to invoke (an actual function)
  • Passing three arguments:
    • the name of the property to observe (as a string)
    • the target object (will be used to look up and invoke a function on)
    • the name of the function to invoke on the target object (as a string).
app/components/my-component.js
import Component from '@ember/component';

export default Component.extend({
  init() {
    this._super(...arguments);

    // the following are equivalent:

    // using three arguments
    this.addObserver('foo', this, 'fooDidChange');

    // using two arguments
    this.addObserver('foo', (...args) => {
      this.fooDidChange(...args);
    });
  },

  fooDidChange() {
    // your custom logic code
  }
});

Observer Methods

Observer methods have the following signature:

app/components/my-component.js
import Component from '@ember/component';

export default Component.extend({
  init() {
    this._super(...arguments);
    this.addObserver('foo', this, 'fooDidChange');
  },

  fooDidChange(sender, key, value, rev) {
    // your code
  }
});

The sender is the object that changed. The key is the property that changes. The value property is currently reserved and unused. The rev is the last property revision of the object when it changed, which you can use to detect if the key value has really changed or not.

Usually you will not need the value or revision parameters at the end. In this case, it is common to write observer methods that take only a sender and key value as parameters or, if you aren't interested in any of these values, to write an observer that has no parameters at all.

Type Parameters
Target

Target

Parameters
key

keyof default

The key to observe

target

Target

The target object to invoke

method

ObserverMethod<Target, default>

The method to invoke

Returns

this

Method

addObserver

Call Signature

ts
addObserver(key, method): this;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/observable.d.ts:338

Parameters
key

keyof default

method

ObserverMethod<default, default>

Returns

this


cacheFor()

ts
cacheFor<K>(key): unknown;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/observable.d.ts:413

Returns the cached value of a computed property, if it exists. This allows you to inspect the value of a computed property without accidentally invoking it if it is intended to be generated lazily.

Type Parameters

K

K extends keyof default

Parameters

key

K

Returns

unknown

The cached value of the computed property, if any

Method

cacheFor


decrementProperty()

ts
decrementProperty(keyName, decrement?): number;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/observable.d.ts:387

Set the value of a property to the current value minus some amount.

javascript
player.decrementProperty('lives');
orc.decrementProperty('health', 5);

Parameters

keyName

keyof default

The name of the property to decrement

decrement?

number

The amount to decrement by. Defaults to 1

Returns

number

The new property value

Method

decrementProperty


destroy()

ts
destroy(): this;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:300

Destroys an object by setting the isDestroyed flag and removing its metadata, which effectively destroys observers and bindings.

If you try to set a property on a destroyed object, an exception will be raised.

Note that destruction is scheduled for the end of the run loop and does not happen immediately. It will set an isDestroying flag immediately.

Returns

this

receiver

Method

destroy


get()

Call Signature

ts
get<K>(key): default[K];

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/observable.d.ts:121

Retrieves the value of a property from the object.

This method is usually similar to using object[keyName] or object.keyName, however it supports both computed properties and the unknownProperty handler.

Because get unifies the syntax for accessing all these kinds of properties, it can make many refactorings easier, such as replacing a simple property with a computed property, or vice versa.

Computed Properties

Computed properties are methods defined with the property modifier declared at the end, such as:

javascript
import { computed } from '@ember/object';

fullName: computed('firstName', 'lastName', function() {
  return this.get('firstName') + ' ' + this.get('lastName');
})

When you call get on a computed property, the function will be called and the return value will be returned instead of the function itself.

Unknown Properties

Likewise, if you try to call get on a property whose value is undefined, the unknownProperty() method will be called on the object. If this method returns any value other than undefined, it will be returned instead. This allows you to implement "virtual" properties that are not defined upfront.

Type Parameters
K

K extends keyof default

Parameters
key

K

Returns

default[K]

The property value or undefined.

Method

get

Call Signature

ts
get(key): unknown;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/observable.d.ts:122

Parameters
key

string

Returns

unknown


getProperties()

Call Signature

ts
getProperties<L>(list): { [Key in keyof default]: default[Key] };

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/observable.d.ts:144

To get the values of multiple properties at once, call getProperties with a list of strings or an array:

javascript
record.getProperties('firstName', 'lastName', 'zipCode');
// { firstName: 'John', lastName: 'Doe', zipCode: '10011' }

is equivalent to:

javascript
record.getProperties(['firstName', 'lastName', 'zipCode']);
// { firstName: 'John', lastName: 'Doe', zipCode: '10011' }
Type Parameters
L

L extends keyof default[]

Parameters
list

L

of keys to get

Returns

{ [Key in keyof default]: default[Key] }

Method

getProperties

Call Signature

ts
getProperties<L>(...list): { [Key in keyof default]: default[Key] };

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/observable.d.ts:149

Type Parameters
L

L extends keyof default[]

Parameters
list

...L

Returns

{ [Key in keyof default]: default[Key] }

Call Signature

ts
getProperties<L>(list): { [Key in string]: unknown };

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/observable.d.ts:154

Type Parameters
L

L extends string[]

Parameters
list

L

Returns

{ [Key in string]: unknown }

Call Signature

ts
getProperties<L>(...list): { [Key in string]: unknown };

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/observable.d.ts:159

Type Parameters
L

L extends string[]

Parameters
list

...L

Returns

{ [Key in string]: unknown }


incrementProperty()

ts
incrementProperty(keyName, increment?): number;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/observable.d.ts:372

Set the value of a property to the current value plus some amount.

javascript
person.incrementProperty('age');
team.incrementProperty('score', 2);

Parameters

keyName

keyof default

The name of the property to increment

increment?

number

The amount to increment by. Defaults to 1

Returns

number

The new property value

Method

incrementProperty


init()

ts
init(_properties): void;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:114

An overridable method called when objects are instantiated. By default, does nothing unless it is overridden during class definition.

Example:

javascript
import EmberObject from '@ember/object';

const Person = EmberObject.extend({
  init() {
    alert(`Name is ${this.get('name')}`);
  }
});

let steve = Person.create({
  name: 'Steve'
});

// alerts 'Name is Steve'.

NOTE: If you do override init for a framework class like Component from @ember/component, be sure to call this._super(...arguments) in your init declaration! If you don't, Ember may not have an opportunity to do important setup work, and you'll see strange behavior in your application.

Parameters

_properties

undefined | object

Returns

void

Method

init


normalize()

ts
normalize(_typeClass, hash): 
  | SingleResourceDocument
  | EmptyResourceDocument;

Defined in: packages/serializer/src/index.ts:266

The normalize method is used to convert a payload received from your external data source into the normalized form store.push() expects. You should override this method, munge the hash and return the normalized payload.

Example:

js
Serializer.extend({
  normalize(modelClass, resourceHash) {
    let data = {
      id:            resourceHash.id,
      type:          modelClass.modelName,
      attributes:    resourceHash
    };
    return { data: data };
  }
})

Parameters

_typeClass

ModelSchema

hash

Record<string, unknown>

Returns

| SingleResourceDocument | EmptyResourceDocument


notifyPropertyChange()

ts
notifyPropertyChange(keyName): this;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/observable.d.ts:249

Convenience method to call propertyWillChange and propertyDidChange in succession.

Notify the observer system that a property has just changed.

Sometimes you need to change a value directly or indirectly without actually calling get() or set() on it. In this case, you can use this method instead. Calling this method will notify all observers that the property has potentially changed value.

Parameters

keyName

string

The property key to be notified about.

Returns

this

Method

notifyPropertyChange


removeObserver()

Call Signature

ts
removeObserver<Target>(
   key, 
   target, 
   method): this;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/observable.d.ts:352

Remove an observer you have previously registered on this object. Pass the same key, target, and method you passed to addObserver() and your target will no longer receive notifications.

Type Parameters
Target

Target

Parameters
key

keyof default

The key to observe

target

Target

The target object to invoke

method

ObserverMethod<Target, default>

The method to invoke

Returns

this

Method

removeObserver

Call Signature

ts
removeObserver(key, method): this;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/observable.d.ts:357

Parameters
key

keyof default

method

ObserverMethod<default, default>

Returns

this


reopen()

ts
reopen(...args): this;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:81

Parameters

args

...(Mixin | Record<string, unknown>)[]

Returns

this


set()

Call Signature

ts
set<K, T>(key, value): T;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/observable.d.ts:208

Sets the provided key or path to the value.

javascript
record.set("key", value);

This method is generally very similar to calling object["key"] = value or object.key = value, except that it provides support for computed properties, the setUnknownProperty() method and property observers.

Computed Properties

If you try to set a value on a key that has a computed property handler defined (see the get() method for an example), then set() will call that method, passing both the value and key instead of simply changing the value itself. This is useful for those times when you need to implement a property that is composed of one or more member properties.

Unknown Properties

If you try to set a value on a key that is undefined in the target object, then the setUnknownProperty() handler will be called instead. This gives you an opportunity to implement complex "virtual" properties that are not predefined on the object. If setUnknownProperty() returns undefined, then set() will simply set the value on the object.

Property Observers

In addition to changing the property, set() will also register a property change with the object. Unless you have placed this call inside of a beginPropertyChanges() and endPropertyChanges(), any "local" observers (i.e. observer methods declared on the same object), will be called immediately. Any "remote" observers (i.e. observer methods declared on another object) will be placed in a queue and called at a later time in a coalesced manner.

Type Parameters
K

K extends keyof default

T

T extends | undefined | string | boolean | default | unknown[] | string[] | Owner | (_typeClass, hash) => | SingleResourceDocument | EmptyResourceDocument | { } | (...args) => this | (_properties) => void | () => this | () => void | () => string | { <K> (key): default[K]; (key): unknown; } | { <L> (list): { [Key in keyof default]: default[Key] }; <L> (...list): { [Key in keyof default]: default[Key] }; <L> (list): { [Key in string]: unknown }; <L> (...list): { [Key in string]: unknown }; } | { <K, T> (key, value): T; <T> (key, value): T; } | { <K, P> (hash): P; <T> (hash): T; } | (keyName) => this | { <Target> (key, target, method): this; (key, method): this; } | { <Target> (key, target, method): this; (key, method): this; } | (keyName, increment?) => number | (keyName, decrement?) => number | (keyName) => boolean | <K>(key) => unknown

Parameters
key

K

value

T

The value to set or null.

Returns

T

The passed value

Method

set

Call Signature

ts
set<T>(key, value): T;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/observable.d.ts:209

Type Parameters
T

T

Parameters
key

string

value

T

Returns

T


setProperties()

Call Signature

ts
setProperties<K, P>(hash): P;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/observable.d.ts:224

Sets a list of properties at once. These properties are set inside a single beginPropertyChanges and endPropertyChanges batch, so observers will be buffered.

javascript
record.setProperties({ firstName: 'Charles', lastName: 'Jolley' });
Type Parameters
K

K extends keyof default

P

P extends { [Key in keyof default]: default[Key] }

Parameters
hash

P

the hash of keys and values to set

Returns

P

The passed in hash

Method

setProperties

Call Signature

ts
setProperties<T>(hash): T;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/observable.d.ts:232

Type Parameters
T

T extends Record<string, unknown>

Parameters
hash

T

Returns

T


toggleProperty()

ts
toggleProperty(keyName): boolean;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/observable.d.ts:401

Set the value of a boolean property to the opposite of its current value.

javascript
starship.toggleProperty('warpDriveEngaged');

Parameters

keyName

keyof default

The name of the property to toggle

Returns

boolean

The new property value

Method

toggleProperty


toString()

ts
toString(): string;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:347

Returns a string representation which attempts to provide more information than Javascript's toString typically does, in a generic way for all Ember objects.

javascript
import EmberObject from '@ember/object';

const Person = EmberObject.extend();
person = Person.create();
person.toString(); //=> "<Person:ember1024>"

If the object's class is not defined on an Ember namespace, it will indicate it is a subclass of the registered superclass:

javascript
const Student = Person.extend();
let student = Student.create();
student.toString(); //=> "<(subclass of Person):ember1025>"

If the method toStringExtension is defined, its return value will be included in the output.

javascript
const Teacher = Person.extend({
  toStringExtension() {
    return this.get('fullName');
  }
});
teacher = Teacher.create();
teacher.toString(); //=> "<Teacher:ember1026:Tom Dale>"

Returns

string

string representation

Method

toString


willDestroy()

ts
willDestroy(): void;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:307

Override to implement teardown.

Returns

void

Method

willDestroy


create()

Call Signature

ts
readonly static create<C>(this): InstanceType<C>;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:487

Creates an instance of a class. Accepts either no arguments, or an object containing values to initialize the newly instantiated object with.

javascript
import EmberObject from '@ember/object';

const Person = EmberObject.extend({
  helloWorld() {
    alert(`Hi, my name is ${this.get('name')}`);
  }
});

let tom = Person.create({
  name: 'Tom Dale'
});

tom.helloWorld(); // alerts "Hi, my name is Tom Dale".

create will call the init function if defined during AnyObject.extend

If no arguments are passed to create, it will not set values to the new instance during initialization:

javascript
let noName = Person.create();
noName.helloWorld(); // alerts undefined

NOTE: For performance reasons, you cannot declare methods or computed properties during create. You should instead declare methods and computed properties when using extend.

Type Parameters
C

C extends typeof CoreObject

Parameters
this

C

Returns

InstanceType<C>

Method

create

For

@ember/object

Static

Call Signature

ts
readonly static create<C, I, K, Args>(this, ...args): InstanceType<C> & MergeArray<Args>;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:488

Creates an instance of a class. Accepts either no arguments, or an object containing values to initialize the newly instantiated object with.

javascript
import EmberObject from '@ember/object';

const Person = EmberObject.extend({
  helloWorld() {
    alert(`Hi, my name is ${this.get('name')}`);
  }
});

let tom = Person.create({
  name: 'Tom Dale'
});

tom.helloWorld(); // alerts "Hi, my name is Tom Dale".

create will call the init function if defined during AnyObject.extend

If no arguments are passed to create, it will not set values to the new instance during initialization:

javascript
let noName = Person.create();
noName.helloWorld(); // alerts undefined

NOTE: For performance reasons, you cannot declare methods or computed properties during create. You should instead declare methods and computed properties when using extend.

Type Parameters
C

C extends typeof CoreObject

I

I extends CoreObject

K

K extends string | number | symbol

Args

Args extends Partial<{ [Key in string | number | symbol]: I[Key] }>[]

Parameters
this

C

args

...Args

Returns

InstanceType<C> & MergeArray<Args>

Method

create

For

@ember/object

Static

detectInstance()

ts
readonly static detectInstance(obj): boolean;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:600

Parameters

obj

unknown

Returns

boolean


extend()

ts
readonly static extend<Statics, Instance, M>(this, ...mixins?): Readonly<Statics> & EmberClassConstructor<Instance> & MergeArray<M>;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:442

Creates a new subclass.

javascript
import EmberObject from '@ember/object';

const Person = EmberObject.extend({
  say(thing) {
    alert(thing);
   }
});

This defines a new subclass of EmberObject: Person. It contains one method: say().

You can also create a subclass from any existing class by calling its extend() method. For example, you might want to create a subclass of Ember's built-in Component class:

javascript
import Component from '@ember/component';

const PersonComponent = Component.extend({
  tagName: 'li',
  classNameBindings: ['isAdministrator']
});

When defining a subclass, you can override methods but still access the implementation of your parent class by calling the special _super() method:

javascript
import EmberObject from '@ember/object';

const Person = EmberObject.extend({
  say(thing) {
    let name = this.get('name');
    alert(`${name} says: ${thing}`);
  }
});

const Soldier = Person.extend({
  say(thing) {
    this._super(`${thing}, sir!`);
  },
  march(numberOfHours) {
    alert(`${this.get('name')} marches for ${numberOfHours} hours.`);
  }
});

let yehuda = Soldier.create({
  name: 'Yehuda Katz'
});

yehuda.say('Yes');  // alerts "Yehuda Katz says: Yes, sir!"

The create() on line #17 creates an instance of the Soldier class. The extend() on line #8 creates a subclass of Person. Any instance of the Person class will not have the march() method.

You can also pass Mixin classes to add additional properties to the subclass.

javascript
import EmberObject from '@ember/object';
import Mixin from '@ember/object/mixin';

const Person = EmberObject.extend({
  say(thing) {
    alert(`${this.get('name')} says: ${thing}`);
  }
});

const SingingMixin = Mixin.create({
  sing(thing) {
    alert(`${this.get('name')} sings: la la la ${thing}`);
  }
});

const BroadwayStar = Person.extend(SingingMixin, {
  dance() {
    alert(`${this.get('name')} dances: tap tap tap tap `);
  }
});

The BroadwayStar class contains three methods: say(), sing(), and dance().

Type Parameters

Statics

Statics

Instance

Instance

M

M extends unknown[]

Parameters

this

Statics & EmberClassConstructor<Instance>

mixins?

...M

One or more Mixin classes

Returns

Readonly<Statics> & EmberClassConstructor<Instance> & MergeArray<M>

Method

extend

Static

For

@ember/object


extractAttributes()

Returns the resource's attributes formatted as a JSON-API "attributes object".

http://jsonapi.org/format/#document-resource-object-attributes

Param

Param

Call Signature

ts
static extractAttributes(modelClass, resourceHash): Object;

Defined in: packages/serializer/src/json.js:632

Parameters
modelClass

Object

resourceHash

Object

Returns

Object

Call Signature

ts
static extractAttributes(modelClass, resourceHash): object;

Defined in: packages/serializer/src/json-api.js:243

Parameters
modelClass

any

resourceHash

any

Returns

object


extractErrors()

ts
readonly static extractErrors(
   store, 
   typeClass, 
   payload, 
   id): Object;

Defined in: packages/serializer/src/json.js:1436

extractErrors is used to extract model errors when a call to Model#save fails with an InvalidError. By default Ember Data expects error information to be located on the errors property of the payload object.

This serializer expects this errors object to be an Array similar to the following, compliant with the https://jsonapi.org/format/#errors specification:

js
{
  "errors": [
    {
      "detail": "This username is already taken!",
      "source": {
        "pointer": "data/attributes/username"
      }
    }, {
      "detail": "Doesn't look like a valid email.",
      "source": {
        "pointer": "data/attributes/email"
      }
    }
  ]
}

The key detail provides a textual description of the problem. Alternatively, the key title can be used for the same purpose.

The nested keys source.pointer detail which specific element of the request data was invalid.

Note that JSON-API also allows for object-level errors to be placed in an object with pointer data, signifying that the problem cannot be traced to a specific attribute:

javascript
{
  "errors": [
    {
      "detail": "Some generic non property error message",
      "source": {
        "pointer": "data"
      }
    }
  ]
}

When turn into a Errors object, you can read these errors through the property base:

handlebars
{{#each @model.errors.base as |error|}}
  <div class="error">
    {{error.message}}
  </div>
{{/each}}

Example of alternative implementation, overriding the default behavior to deal with a different format of errors:

app/serializers/post.js
js
import JSONSerializer from '@ember-data/serializer/json';

export default class PostSerializer extends JSONSerializer {
  extractErrors(store, typeClass, payload, id) {
    if (payload && typeof payload === 'object' && payload._problems) {
      payload = payload._problems;
      this.normalizeErrors(typeClass, payload);
    }
    return payload;
  }
}

Parameters

store

Store

typeClass

Model

payload

Object

id

string | number

Returns

Object

json The deserialized errors


extractId()

ts
readonly static extractId(modelClass, resourceHash): string;

Defined in: packages/serializer/src/json.js:616

Returns the resource's ID.

Parameters

modelClass

Object

resourceHash

Object

Returns

string


extractMeta()

ts
readonly static extractMeta(
   store, 
   modelClass, 
   payload): any;

Defined in: packages/serializer/src/json.js:1343

extractMeta is used to deserialize any meta information in the adapter payload. By default Ember Data expects meta information to be located on the meta property of the payload object.

Example

app/serializers/post.js
js
import JSONSerializer from '@ember-data/serializer/json';

export default class PostSerializer extends JSONSerializer {
  extractMeta(store, typeClass, payload) {
    if (payload && payload.hasOwnProperty('_pagination')) {
      let meta = payload._pagination;
      delete payload._pagination;
      return meta;
    }
  }
}

Parameters

store

Store

modelClass

Model

payload

Object

Returns

any


extractPolymorphicRelationship()

ts
readonly static extractPolymorphicRelationship(
   relationshipModelName, 
   relationshipHash, 
   relationshipOptions): Object;

Defined in: packages/serializer/src/json.js:699

Returns a polymorphic relationship formatted as a JSON-API "relationship object".

http://jsonapi.org/format/#document-resource-object-relationships

relationshipOptions is a hash which contains more information about the polymorphic relationship which should be extracted:

  • resourceHash complete hash of the resource the relationship should be extracted from
  • relationshipKey key under which the value for the relationship is extracted from the resourceHash
  • relationshipMeta meta information about the relationship

Parameters

relationshipModelName

Object

relationshipHash

Object

relationshipOptions

Object

Returns

Object


extractRelationship()

Returns a relationship formatted as a JSON-API "relationship object".

http://jsonapi.org/format/#document-resource-object-relationships

Param

Param

Call Signature

ts
static extractRelationship(relationshipModelName, relationshipHash): Object;

Defined in: packages/serializer/src/json.js:656

Parameters
relationshipModelName

Object

relationshipHash

Object

Returns

Object

Call Signature

ts
static extractRelationship(relationshipHash): Object;

Defined in: packages/serializer/src/json-api.js:275

Returns a relationship formatted as a JSON-API "relationship object".

http://jsonapi.org/format/#document-resource-object-relationships

Parameters
relationshipHash

Object

Returns

Object

Param
Param

extractRelationships()

ts
static extractRelationships(modelClass, resourceHash): Object;

Defined in: packages/serializer/src/json.js:713

Returns the resource's relationships formatted as a JSON-API "relationships object".

http://jsonapi.org/format/#document-resource-object-relationships

Parameters

modelClass

Object

resourceHash

Object

Returns

Object


keyForAttribute()

ts
static keyForAttribute(key, method): string;

Defined in: packages/serializer/src/json.js:1507

keyForAttribute can be used to define rules for how to convert an attribute name in your model to a key in your JSON.

Example

app/serializers/application.js
js
import JSONSerializer from '@ember-data/serializer/json';
import { underscore } from '<app-name>/utils/string-utils';

export default class ApplicationSerializer extends JSONSerializer {
  keyForAttribute(attr, method) {
    return underscore(attr).toUpperCase();
  }
}

Parameters

key

string

method

string

Returns

string

normalized key


ts
readonly static keyForLink(key, kind): string;

Defined in: packages/serializer/src/json.js:1548

keyForLink can be used to define a custom key when deserializing link properties.

Parameters

key

string

kind

string

belongsTo or hasMany

Returns

string

normalized key


keyForRelationship()

ts
static keyForRelationship(
   key, 
   typeClass, 
   method): string;

Defined in: packages/serializer/src/json.js:1535

keyForRelationship can be used to define a custom key when serializing and deserializing relationship properties. By default JSONSerializer does not provide an implementation of this method.

Example

app/serializers/post.js
js
import JSONSerializer from '@ember-data/serializer/json';
import { underscore } from '<app-name>/utils/string-utils';

export default class PostSerializer extends JSONSerializer {
  keyForRelationship(key, relationship, method) {
    return `rel_${underscore(key)}`;
  }
}

Parameters

key

string

typeClass

string

method

string

Returns

string

normalized key


modelNameFromPayloadKey()

ts
static modelNameFromPayloadKey(key): string;

Defined in: packages/serializer/src/json.js:781

Dasherizes the model name in the payload

Parameters

key

string

Returns

string

the model's modelName


normalize()

Normalizes a part of the JSON payload returned by the server. You should override this method, munge the hash and call super if you have generic normalization to do.

It takes the type of the record that is being normalized (as a Model class), the property where the hash was originally found, and the hash to normalize.

You can use this method, for example, to normalize underscored keys to camelized or other general-purpose normalizations.

Example

app/serializers/application.js
js
import JSONSerializer from '@ember-data/serializer/json';
import { underscore } from '<app-name>/utils/string-utils';
import { get } from '@ember/object';

export default class ApplicationSerializer extends JSONSerializer {
  normalize(typeClass, hash) {
    let fields = typeClass.fields;

    fields.forEach(function(type, field) {
      let payloadField = underscore(field);
      if (field === payloadField) { return; }

      hash[field] = hash[payloadField];
      delete hash[payloadField];
    });

    return super.normalize(...arguments);
  }
}

Param

Param

Call Signature

ts
static normalize(modelClass, resourceHash): Object;

Defined in: packages/serializer/src/json.js:582

Parameters
modelClass

any

resourceHash

any

Returns

Object

Call Signature

ts
static normalize(modelClass, resourceHash): object;

Defined in: packages/serializer/src/json-api.js:368

Parameters
modelClass

any

resourceHash

any

Returns

object

data
ts
data: object;
data.attributes
ts
data.attributes: object;
data.id
ts
data.id: any;
data.relationships
ts
data.relationships: Object;
data.type
ts
data.type: string;

normalizeArrayResponse()

ts
readonly static normalizeArrayResponse(
   store, 
   primaryModelClass, 
   payload, 
   id, 
   requestType): Object;

Defined in: packages/serializer/src/json.js:489

normalizeQueryResponse, normalizeFindManyResponse, and normalizeFindHasManyResponse delegate to this method by default.

Parameters

store

Store

primaryModelClass

Model

payload

Object

id

string | number

requestType

string

Returns

Object

JSON-API Document

Since

1.13.0


normalizeCreateRecordResponse()

ts
readonly static normalizeCreateRecordResponse(
   store, 
   primaryModelClass, 
   payload, 
   id, 
   requestType, ...
   args): Object;

Defined in: packages/serializer/src/json.js:404

Called by the default normalizeResponse implementation when the type of request is createRecord

Parameters

store

Store

primaryModelClass

Model

payload

Object

id

string | number

requestType

string

args

...any

Returns

Object

JSON-API Document

Since

1.13.0


normalizeDeleteRecordResponse()

ts
readonly static normalizeDeleteRecordResponse(
   store, 
   primaryModelClass, 
   payload, 
   id, 
   requestType, ...
   args): Object;

Defined in: packages/serializer/src/json.js:421

Called by the default normalizeResponse implementation when the type of request is deleteRecord

Parameters

store

Store

primaryModelClass

Model

payload

Object

id

string | number

requestType

string

args

...any

Returns

Object

JSON-API Document

Since

1.13.0


normalizeFindAllResponse()

ts
readonly static normalizeFindAllResponse(
   store, 
   primaryModelClass, 
   payload, 
   id, 
   requestType, ...
   args): Object;

Defined in: packages/serializer/src/json.js:319

Called by the default normalizeResponse implementation when the type of request is findAll

Parameters

store

Store

primaryModelClass

Model

payload

Object

id

string | number

requestType

string

args

...any

Returns

Object

JSON-API Document

Since

1.13.0


normalizeFindBelongsToResponse()

ts
readonly static normalizeFindBelongsToResponse(
   store, 
   primaryModelClass, 
   payload, 
   id, 
   requestType, ...
   args): Object;

Defined in: packages/serializer/src/json.js:336

Called by the default normalizeResponse implementation when the type of request is findBelongsTo

Parameters

store

Store

primaryModelClass

Model

payload

Object

id

string | number

requestType

string

args

...any

Returns

Object

JSON-API Document

Since

1.13.0


normalizeFindHasManyResponse()

ts
readonly static normalizeFindHasManyResponse(
   store, 
   primaryModelClass, 
   payload, 
   id, 
   requestType, ...
   args): Object;

Defined in: packages/serializer/src/json.js:353

Called by the default normalizeResponse implementation when the type of request is findHasMany

Parameters

store

Store

primaryModelClass

Model

payload

Object

id

string | number

requestType

string

args

...any

Returns

Object

JSON-API Document

Since

1.13.0


normalizeFindManyResponse()

ts
readonly static normalizeFindManyResponse(
   store, 
   primaryModelClass, 
   payload, 
   id, 
   requestType, ...
   args): Object;

Defined in: packages/serializer/src/json.js:370

Called by the default normalizeResponse implementation when the type of request is findMany

Parameters

store

Store

primaryModelClass

Model

payload

Object

id

string | number

requestType

string

args

...any

Returns

Object

JSON-API Document

Since

1.13.0


normalizeFindRecordResponse()

ts
readonly static normalizeFindRecordResponse(
   store, 
   primaryModelClass, 
   payload, 
   id, 
   requestType, ...
   args): Object;

Defined in: packages/serializer/src/json.js:285

Called by the default normalizeResponse implementation when the type of request is findRecord

Parameters

store

Store

primaryModelClass

Model

payload

Object

id

string | number

requestType

string

args

...any

Returns

Object

JSON-API Document

Since

1.13.0


normalizeQueryRecordResponse()

Called by the default normalizeResponse implementation when the type of request is queryRecord

Since

1.13.0

Param

Param

Param

Param

Param

Call Signature

ts
static normalizeQueryRecordResponse(
   store, 
   primaryModelClass, 
   payload, 
   id, 
   requestType, ...
   args): Object;

Defined in: packages/serializer/src/json.js:302

Parameters
store

Store

primaryModelClass

Model

payload

Object

id

string | number

requestType

string

args

...any

Returns

Object

Call Signature

ts
static normalizeQueryRecordResponse(...args): any;

Defined in: packages/serializer/src/json-api.js:232

Parameters
args

...any

Returns

any


normalizeQueryResponse()

ts
readonly static normalizeQueryResponse(
   store, 
   primaryModelClass, 
   payload, 
   id, 
   requestType, ...
   args): Object;

Defined in: packages/serializer/src/json.js:387

Called by the default normalizeResponse implementation when the type of request is query

Parameters

store

Store

primaryModelClass

Model

payload

Object

id

string | number

requestType

string

args

...any

Returns

Object

JSON-API Document

Since

1.13.0


normalizeResponse()

ts
readonly static normalizeResponse(
   store, 
   primaryModelClass, 
   payload, 
   id, 
   requestType, ...
   args): Object;

Defined in: packages/serializer/src/json.js:247

The normalizeResponse method is used to normalize a payload from the server to a JSON-API Document.

http://jsonapi.org/format/#document-structure

This method delegates to a more specific normalize method based on the requestType.

To override this method with a custom one, make sure to call return super.normalizeResponse(store, primaryModelClass, payload, id, requestType) with your pre-processed data.

Here's an example of using normalizeResponse manually:

javascript
socket.on('message', function(message) {
  let data = message.data;
  let modelClass = store.modelFor(data.modelName);
  let serializer = store.serializerFor(data.modelName);
  let normalized = serializer.normalizeSingleResponse(store, modelClass, data, data.id);

  store.push(normalized);
});

Parameters

store

Store

primaryModelClass

Model

payload

Object

id

string | number

requestType

string

args

...any

Returns

Object

JSON-API Document

Since

1.13.0


normalizeSaveResponse()

ts
readonly static normalizeSaveResponse(
   store, 
   primaryModelClass, 
   payload, 
   id, 
   requestType, ...
   args): Object;

Defined in: packages/serializer/src/json.js:455

normalizeUpdateRecordResponse, normalizeCreateRecordResponse and normalizeDeleteRecordResponse delegate to this method by default.

Parameters

store

Store

primaryModelClass

Model

payload

Object

id

string | number

requestType

string

args

...any

Returns

Object

JSON-API Document

Since

1.13.0


normalizeSingleResponse()

ts
readonly static normalizeSingleResponse(
   store, 
   primaryModelClass, 
   payload, 
   id, 
   requestType): Object;

Defined in: packages/serializer/src/json.js:472

normalizeQueryResponse and normalizeFindRecordResponse delegate to this method by default.

Parameters

store

Store

primaryModelClass

Model

payload

Object

id

string | number

requestType

string

Returns

Object

JSON-API Document

Since

1.13.0


normalizeUpdateRecordResponse()

ts
readonly static normalizeUpdateRecordResponse(
   store, 
   primaryModelClass, 
   payload, 
   id, 
   requestType, ...
   args): Object;

Defined in: packages/serializer/src/json.js:438

Called by the default normalizeResponse implementation when the type of request is updateRecord

Parameters

store

Store

primaryModelClass

Model

payload

Object

id

string | number

requestType

string

args

...any

Returns

Object

JSON-API Document

Since

1.13.0


payloadKeyFromModelName()

ts
static payloadKeyFromModelName(modelName): string;

Defined in: packages/serializer/src/json-api.js:364

Converts the model name to a pluralized version of the model name.

For example post would be converted to posts and student-assesment would be converted to student-assesments.

Parameters

modelName

string

Returns

string


proto()

ts
readonly static proto(): CoreObject;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:649

Returns

CoreObject


pushPayload()

ts
static pushPayload(store, payload): void;

Defined in: packages/serializer/src/json-api.js:212

Normalize some data and push it into the store.

Parameters

store

Store

payload

Object

Returns

void


reopenClass()

ts
readonly static reopenClass<C>(this, ...mixins): C;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:595

Augments a constructor's own properties and functions:

javascript
import EmberObject from '@ember/object';

const MyObject = EmberObject.extend({
  name: 'an object'
});

MyObject.reopenClass({
  canBuild: false
});

MyObject.canBuild; // false
o = MyObject.create();

In other words, this creates static properties and functions for the class. These are only available on the class and not on any instance of that class.

javascript
import EmberObject from '@ember/object';

const Person = EmberObject.extend({
  name: '',
  sayHello() {
    alert(`Hello. My name is ${this.get('name')}`);
  }
});

Person.reopenClass({
  species: 'Homo sapiens',

  createPerson(name) {
    return Person.create({ name });
  }
});

let tom = Person.create({
  name: 'Tom Dale'
});
let yehuda = Person.createPerson('Yehuda Katz');

tom.sayHello(); // "Hello. My name is Tom Dale"
yehuda.sayHello(); // "Hello. My name is Yehuda Katz"
alert(Person.species); // "Homo sapiens"

Note that species and createPerson are not valid on the tom and yehuda variables. They are only valid on Person.

To add functions and properties to instances of a constructor by extending the constructor's prototype see reopen

Type Parameters

C

C extends typeof CoreObject

Parameters

this

C

mixins

...(Mixin | Record<string, unknown>)[]

Returns

C

Method

reopenClass

For

@ember/object

Static


serialize()

Called when a record is saved in order to convert the record into JSON.

By default, it creates a JSON object with a key for each attribute and belongsTo relationship.

For example, consider this model:

app/models/comment.js
js
import Model, { attr, belongsTo } from '@ember-data/model';

export default class CommentModel extends Model {
  @attr title;
  @attr body;

  @belongsTo('user') author;
}

The default serialization would create a JSON object like:

javascript
{
  "title": "Rails is unagi",
  "body": "Rails? Omakase? O_O",
  "author": 12
}

By default, attributes are passed through as-is, unless you specified an attribute type (attr('date')). If you specify a transform, the JavaScript value will be serialized when inserted into the JSON hash.

By default, belongs-to relationships are converted into IDs when inserted into the JSON hash.

IDs

serialize takes an options hash with a single option: includeId. If this option is true, serialize will, by default include the ID in the JSON object it builds.

The adapter passes in includeId: true when serializing a record for createRecord, but not for updateRecord.

Customization

Your server may expect a different JSON format than the built-in serialization format.

In that case, you can implement serialize yourself and return a JSON hash of your choosing.

app/serializers/post.js
js
import JSONSerializer from '@ember-data/serializer/json';

export default class PostSerializer extends JSONSerializer {
  serialize(snapshot, options) {
    let json = {
      POST_TTL: snapshot.attr('title'),
      POST_BDY: snapshot.attr('body'),
      POST_CMS: snapshot.hasMany('comments', { ids: true })
    };

    if (options.includeId) {
      json.POST_ID_ = snapshot.id;
    }

    return json;
  }
}

Customizing an App-Wide Serializer

If you want to define a serializer for your entire application, you'll probably want to use eachAttribute and eachRelationship on the record.

app/serializers/application.js
js
import JSONSerializer from '@ember-data/serializer/json';
import { singularize } from '<app-name>/utils/string-utils';

export default class ApplicationSerializer extends JSONSerializer {
  serialize(snapshot, options) {
    let json = {};

    snapshot.eachAttribute((name) => {
      json[serverAttributeName(name)] = snapshot.attr(name);
    });

    snapshot.eachRelationship((name, relationship) => {
      if (relationship.kind === 'hasMany') {
        json[serverHasManyName(name)] = snapshot.hasMany(name, { ids: true });
      }
    });

    if (options.includeId) {
      json.ID_ = snapshot.id;
    }

    return json;
  }
}

function serverAttributeName(attribute) {
  return attribute.underscore().toUpperCase();
}

function serverHasManyName(name) {
  return serverAttributeName(singularize(name)) + "_IDS";
}

This serializer will generate JSON that looks like this:

javascript
{
  "TITLE": "Rails is omakase",
  "BODY": "Yep. Omakase.",
  "COMMENT_IDS": [ "1", "2", "3" ]
}

Tweaking the Default JSON

If you just want to do some small tweaks on the default JSON, you can call super.serialize first and make the tweaks on the returned JSON.

app/serializers/post.js
js
import JSONSerializer from '@ember-data/serializer/json';

export default class PostSerializer extends JSONSerializer {
  serialize(snapshot, options) {
    let json = super.serialize(...arguments);

    json.subject = json.title;
    delete json.title;

    return json;
  }
}

Param

Param

Call Signature

ts
static serialize(snapshot, options): Object;

Defined in: packages/serializer/src/json.js:1080

Parameters
snapshot

Snapshot

options

Object

Returns

Object

Call Signature

ts
static serialize(
   snapshot, 
   options, ...
   args): Object;

Defined in: packages/serializer/src/json-api.js:623

Called when a record is saved in order to convert the record into JSON.

For example, consider this model:

app/models/comment.js
js
import Model, { attr, belongsTo } from '@ember-data/model';

export default class CommentModel extends Model {
  @attr title;
  @attr body;

  @belongsTo('user', { async: false, inverse: null })
  author;
}

The default serialization would create a JSON-API resource object like:

javascript
{
  "data": {
    "type": "comments",
    "attributes": {
      "title": "Rails is unagi",
      "body": "Rails? Omakase? O_O",
    },
    "relationships": {
      "author": {
        "data": {
          "id": "12",
          "type": "users"
        }
      }
    }
  }
}

By default, attributes are passed through as-is, unless you specified an attribute type (attr('date')). If you specify a transform, the JavaScript value will be serialized when inserted into the attributes hash.

Belongs-to relationships are converted into JSON-API resource identifier objects.

IDs

serialize takes an options hash with a single option: includeId. If this option is true, serialize will, by default include the ID in the JSON object it builds.

The JSONAPIAdapter passes in includeId: true when serializing a record for createRecord or updateRecord.

Customization

Your server may expect data in a different format than the built-in serialization format.

In that case, you can implement serialize yourself and return data formatted to match your API's expectations, or override the invoked adapter method and do the serialization in the adapter directly by using the provided snapshot.

If your API's format differs greatly from the JSON:API spec, you should consider authoring your own adapter and serializer instead of extending this class.

app/serializers/post.js
js
import JSONAPISerializer from '@ember-data/serializer/json-api';

export default class PostSerializer extends JSONAPISerializer {
  serialize(snapshot, options) {
    let json = {
      POST_TTL: snapshot.attr('title'),
      POST_BDY: snapshot.attr('body'),
      POST_CMS: snapshot.hasMany('comments', { ids: true })
    };

    if (options.includeId) {
      json.POST_ID_ = snapshot.id;
    }

    return json;
  }
}

Customizing an App-Wide Serializer

If you want to define a serializer for your entire application, you'll probably want to use eachAttribute and eachRelationship on the record.

app/serializers/application.js
js
import JSONAPISerializer from '@ember-data/serializer/json-api';
import { underscore, singularize } from '<app-name>/utils/string-utils';

export default class ApplicationSerializer extends JSONAPISerializer {
  serialize(snapshot, options) {
    let json = {};

    snapshot.eachAttribute((name) => {
      json[serverAttributeName(name)] = snapshot.attr(name);
    });

    snapshot.eachRelationship((name, relationship) => {
      if (relationship.kind === 'hasMany') {
        json[serverHasManyName(name)] = snapshot.hasMany(name, { ids: true });
      }
    });

    if (options.includeId) {
      json.ID_ = snapshot.id;
    }

    return json;
  }
}

function serverAttributeName(attribute) {
  return underscore(attribute).toUpperCase();
}

function serverHasManyName(name) {
  return serverAttributeName(singularize(name)) + '_IDS';
}

This serializer will generate JSON that looks like this:

javascript
{
  "TITLE": "Rails is omakase",
  "BODY": "Yep. Omakase.",
  "COMMENT_IDS": [ "1", "2", "3" ]
}

Tweaking the Default Formatting

If you just want to do some small tweaks on the default JSON:API formatted response, you can call super.serialize first and make the tweaks on the returned object.

app/serializers/post.js
js
import JSONAPISerializer from '@ember-data/serializer/json-api';

export default class PostSerializer extends JSONAPISerializer {
  serialize(snapshot, options) {
    let json = super.serialize(...arguments);

    json.data.attributes.subject = json.data.attributes.title;
    delete json.data.attributes.title;

    return json;
  }
}
Parameters
snapshot

Snapshot

options

Object

args

...any

Returns

Object

json

Param
Param

serializeAttribute()

serializeAttribute can be used to customize how attr properties are serialized

For example if you wanted to ensure all your attributes were always serialized as properties on an attributes object you could write:

app/serializers/application.js
js
import JSONSerializer from '@ember-data/serializer/json';

export default class ApplicationSerializer extends JSONSerializer {
  serializeAttribute(snapshot, json, key, attributes) {
    json.attributes = json.attributes || {};
    super.serializeAttribute(snapshot, json.attributes, key, attributes);
  }
}

Param

Param

Param

Param

Call Signature

ts
static serializeAttribute(
   snapshot, 
   json, 
   key, 
   attribute): void;

Defined in: packages/serializer/src/json.js:1162

Parameters
snapshot

Snapshot

json

Object

key

string

attribute

Object

Returns

void

Call Signature

ts
static serializeAttribute(
   snapshot, 
   json, 
   key, 
   attribute): void;

Defined in: packages/serializer/src/json-api.js:630

Parameters
snapshot

any

json

any

key

any

attribute

any

Returns

void


serializeBelongsTo()

serializeBelongsTo can be used to customize how belongsTo properties are serialized.

Example

app/serializers/post.js
js
import JSONSerializer from '@ember-data/serializer/json';

export default class PostSerializer extends JSONSerializer {
  serializeBelongsTo(snapshot, json, relationship) {
    let key = relationship.name;
    let belongsTo = snapshot.belongsTo(key);

    key = this.keyForRelationship ? this.keyForRelationship(key, "belongsTo", "serialize") : key;

    json[key] = !belongsTo ? null : belongsTo.record.toJSON();
  }
}

Param

Param

Param

Call Signature

ts
static serializeBelongsTo(
   snapshot, 
   json, 
   relationship): void;

Defined in: packages/serializer/src/json.js:1210

Parameters
snapshot

Snapshot

json

Object

relationship

Object

Returns

void

Call Signature

ts
static serializeBelongsTo(
   snapshot, 
   json, 
   relationship): void;

Defined in: packages/serializer/src/json-api.js:653

Parameters
snapshot

any

json

any

relationship

any

Returns

void


serializeHasMany()

serializeHasMany can be used to customize how hasMany properties are serialized.

Example

app/serializers/post.js
js
import JSONSerializer from '@ember-data/serializer/json';

export default class PostSerializer extends JSONSerializer {
  serializeHasMany(snapshot, json, relationship) {
    let key = relationship.name;
    if (key === 'comments') {
      return;
    } else {
      super.serializeHasMany(...arguments);
    }
  }
}

Param

Param

Param

Call Signature

ts
static serializeHasMany(
   snapshot, 
   json, 
   relationship): void;

Defined in: packages/serializer/src/json.js:1263

Parameters
snapshot

Snapshot

json

Object

relationship

Object

Returns

void

Call Signature

ts
static serializeHasMany(
   snapshot, 
   json, 
   relationship): void;

Defined in: packages/serializer/src/json-api.js:684

Parameters
snapshot

any

json

any

relationship

any

Returns

void


serializeIntoHash()

ts
readonly static serializeIntoHash(
   hash, 
   typeClass, 
   snapshot, 
   options): void;

Defined in: packages/serializer/src/json.js:1133

You can use this method to customize how a serialized record is added to the complete JSON hash to be sent to the server. By default the JSON Serializer does not namespace the payload and just sends the raw serialized JSON object. If your server expects namespaced keys, you should consider using the RESTSerializer. Otherwise you can override this method to customize how the record is added to the hash. The hash property should be modified by reference.

For example, your server may expect underscored root objects.

app/serializers/application.js
js
import RESTSerializer from '@ember-data/serializer/rest';
import { underscoren} from '<app-name>/utils/string-utils';

export default class ApplicationSerializer extends RESTSerializer {
  serializeIntoHash(data, type, snapshot, options) {
    let root = underscore(type.modelName);
    data[root] = this.serialize(snapshot, options);
  }
}

Parameters

hash

Object

typeClass

Model

snapshot

Snapshot

options

Object

Returns

void


serializePolymorphicType()

ts
readonly static serializePolymorphicType(): void;

Defined in: packages/serializer/src/json.js:1315

You can use this method to customize how polymorphic objects are serialized. Objects are considered to be polymorphic if { polymorphic: true } is pass as the second argument to the belongsTo function.

Example

app/serializers/comment.js
js
import JSONSerializer from '@ember-data/serializer/json';

export default class CommentSerializer extends JSONSerializer {
  serializePolymorphicType(snapshot, json, relationship) {
    let key = relationship.name;
    let belongsTo = snapshot.belongsTo(key);

    key = this.keyForAttribute ? this.keyForAttribute(key, 'serialize') : key;

    if (!belongsTo) {
      json[key + '_type'] = null;
    } else {
      json[key + '_type'] = belongsTo.modelName;
    }
  }
}

Returns

void


shouldSerializeHasMany()

ts
readonly static shouldSerializeHasMany(
   snapshot, 
   key, 
   relationship): boolean;

Defined in: packages/serializer/src/json.js:918

Check if the given hasMany relationship should be serialized

By default only many-to-many and many-to-none relationships are serialized. This could be configured per relationship by Serializer's attrs object.

Parameters

snapshot

Snapshot

key

string

relationship

RelationshipSchema

Returns

boolean

true if the hasMany relationship should be serialized


toString()

ts
readonly static toString(): string;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:650

Returns

string


willReopen()

ts
readonly static willReopen(): void;

Defined in: node_modules/.pnpm/ember-s_b51cd27d01243d453ba52dedc3d113b0/node_modules/ember-source/types/stable/@ember/object/core.d.ts:533

Returns

void

Released under the MIT License.