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]