Transforms
A transform is a mixin which provides methods to transform a resource's attribute values.
The TransformsMixin
defines methods to serialize
and deserialize
a date(time) attribute value to and from ISO Format. Define a Date
(type) attribute in your resource using the attr('date')
helper.
Define attribute types string
, boolean
, number
, object
, array
, date
in your resource prototype. To transform the attribute generate a "transforms" mixin. In the generated mixin define any types you need to serialize/deserialize. Then use the type when defining a resource attribute, e.g. attr('array')
.
The application serializer includes a Date
type transform. The serializer transforms a data attribute using the methods serializeDateAttribute
and deserializeDateAttribute
. The resource attribute can have any name, and is setup using the attr('date')
helper.
See the TransformDateAttribute
prototype in the addon/utils
folder of this library.
Use a transform module anywhere in your application. A serializer uses a transform when processing a server request and response. Also, your application may import a transform module for use anywhere. One example is to use the transform for a set of values in a dropdown component in the user interface.
A serializer may also use any transformations you define. The serializer uses a convention based on the attribute type to find the transform method, e.g. serializeUpdatedAtAttribute
and deserializeUpdatedAtAttribute
. In your resource use the custom type with the attr
helper like so: attr('updated-at', false /*read only*/)
.
Likewise, define transforms based on the name of a resource attribute. The serializer will look use a convention to lookup the transform methods. Define transform methods based on the name of an attribute, e.g. to transform a status
attribute define serializeStatusAttribute
and deserializeStatusAttribute
.
A method based on the name of the attribute takes precedence over a transform method based on the type of the attribute (e.g. date). For example, the serializer will call serializeUpdatedAteAttribute
instead of serializeDateAttribute
when the resource defines its updated-at
property using "updated-at": attr('date')
.
Below is the default Date
type transform used in combination with attr('date')
.
/**
@module ember-jsonapi-resources
@submodule transforms
**/
import Ember from 'ember';
import { dateTransform } from 'ember-jsonapi-resources/utils/transforms';
/**
@class TransformsMixin
*/
export default Ember.Mixin.create({
/**
@method serializeDateAttribute
@param {Date|String} date
@return {String|Null} date value as ISO String for JSON payload, or null
*/
serializeDateAttribute(date) {
return dateTransform.serialize(date);
},
/**
@method deserializeDateAttribute
@param {String} date usually in ISO format, must be a valid argument for Date
@return {Date|Null} date value from JSON payload, or null
*/
deserializeDateAttribute(date) {
return dateTransform.deserialize(date);
}
});
Import A transform utility module anywhere in an Ember application. Use the import
keyword in a component. Most often a serializer will use a transform mixin.
Below is the transforms
utility prototype used by the Date
type transform:
ember-jsonapi-resources/addon/utils/transforms
/**
@module ember-jsonapi-resources
@submodule utils
**/
import { isBlank, isType } from 'ember-jsonapi-resources/utils/is';
/**
@class TransformDateAttribute
*/
class TransformDateAttribute {
/**
@method serialize
@param {Date|String} date
@return {String|Null} date value as ISO String for JSON payload, or null
*/
serialize(date) {
if (isBlank(date) || date === '') {
date = null;
} else if (isType('date', date)) {
date = date.toISOString();
} else if (isType('string', date)) {
date = new Date(date);
}
return (date) ? date : null;
}
/**
@method deserialize
@param {String} date usually in ISO format, must be a valid argument for Date
@return {Date|Null} date value from JSON payload, or null
*/
deserialize(date) {
if (isBlank(date)) {
date = null;
} else if (isType('string', date) || isType('number', date)) {
date = new Date(date);
}
return (date) ? date : null;
}
}
export let dateTransform = new TransformDateAttribute();
A transform defines value formatting for your resource attributes using serialize
and deserialize
functions. The JSONAPI::Resources gem for Rails applications provides Value Formatters. In this library "transforms" are the same as "value formatters" but intended for general use in a client application. Ember Data has a Transform
feature as well.
Generators
Use the jsonapi-transform-mixin
generator to create a transform mixin. Then import the mixin for use in a serializer, or elsewhere.
Use the jsonapi-dictionary
generator to create a utility module for defining key value pairs for transforming an attribute.
Use the jsonapi-transform
generator to create a class for desializing/deserializing a value.
Use these generators together to provide keys/value pairs to transform an attribute with.
To create a custom transform for a resource attribute named status
:
ember g jsonapi-dictionary status active:Active pending:Pending archived:Archive
ember g jsonapi-transform status
ember g jsonapi-transform-mixin post status
The generated app/utils/dictionaries/status.js
file:
const dictionary = Object.create(null);
dictionary["active"] = "Active";
dictionary["pending"] = "Pending";
dictionary["archived"] = "Archive";
export default Object.freeze(dictionary);
The generated app/transforms/status.js
file:
import TransformMap from 'ember-jsonapi-resources/utils/transform-map';
import dictionary from '../utils/dictionaries/status';
class TransformStatusAttribute extends TransformMap {
deserialize(serialized) {
return this.lookup(serialized);
}
serialize(deserialized) {
return this.lookup(deserialized, 'values');
}
}
export default new TransformStatusAttribute(dictionary);
The generated app/mixins/post-transforms.js
file:
import Ember from 'ember';
import statusTransform from '../transforms/status';
export default Ember.Mixin.create({
deserializeStatusAttribute(serialized) {
return statusTransform.deserialize(serialized);
},
serializeStatusAttribute(deserialized) {
return statusTransform.serialize(deserialized);
}
});
To add the transform to a PostSerializer
use the mixin in a serializer. The jsonapi-resoruce
generator creates a resource and associated initializer, serializer, etc.
ember g jsonapi-resource post title:string body:string status:string
An example of the generated app/serializers/post.js
file:
import ApplicationSerializer from './application';
export default ApplicationSerializer.extend({
});
To add any transform mixins you create, import then apply the mixin to the serializer prototype.
import ApplicationSerializer from './application';
import PostTransformsMixin from '../mixins/post-transforms.js'
export default ApplicationSerializer.extend(PostTransformsMixin);
Use Anywhere
Use a transform object anywhere in your code.
For example: A dropdown component for a form field may use display names and values found in a dictionary utility.
Import the transform in a component:
import statusTransform from '../transforms/status';
To use the values in your dropdown component:
statuses: statusTransform.values
Or, set a default value using the first value of the dictionary utility:
selected: statusTransform.values[0]