Built-in transformers
Now that we are familiar with the concept of transformers and how it works, let's see the built-in transformers available with Banquette.
Root transformers
Json
Root Model <==> StringThe Json transformer converts a model into a JSON string and vice-versa.
Only properties decorated with the @Json() decorator will be included:
class Article {
@Json()
public title: string;
}
@Json() takes an optional TransformerInterface object as parameter to transform the value of the property:
class Article {
// Primitive will ensure the value is a number.
@Json(Primitive(Type.Number))
public views: number;
}
Pojo
Root Model <==> Object literalThe Pojo transformer converts a model into an object literal and vice-versa.
Only properties decorated with the @Pojo() decorator will be included:
class Article {
@Pojo()
public title: string;
}
@Pojo() takes an optional TransformerInterface object as parameter to transform the value of the property:
class Article {
// Primitive will ensure the value is a number.
@Pojo(Primitive(Type.Number))
public views: number;
}
Form
Root Model <==> FormObjectThe Form transformer converts a model into a FormObject and vice-versa.
It's part of @banquette/model-form, please refer to the dedicated section for more information.
Property transformers
Primitive
Value Any <==> PrimitiveEnsure the output type matches the ones given as parameters.
import { Primivite, Type } from '@banquette/model';
// Ensure `transform` outputs a `String`
Primivite(Type.String);
// Ensure `transform` outputs a `String`
// and `transformInverse` outputs a `Number`.
Primivite(Type.String, Type.Number);
// Ensure `transform` outputs a `String` OR a `null`.
// and `transformInverse` outputs a `String`.
Primivite(Type.String | Type.Null, Type.String);
Click here to see the list available types
enum Type {
/**
* Ensure the output is a scalar or compound type.
* If not, converts it to string.
*/
Any = 0,
/**
* Convert the input into a string.
*/
String = 1,
/**
* Convert the input into a number.
*/
Number = 2,
/**
* Convert the input into a number an round it.
*/
Integer = 4,
/**
* Convert the input into a boolean.
*/
Boolean = 8,
/**
* Allow the "null" value as input.
*
* Setting thins in conjunction with "Type.String" (Type.String | Type.Null) means that
* if "null" is given as input, it will not be converted to an empty string.
*/
Null = 16
}
| Option | Description |
|---|---|
| transformType | Type to guarantee when doing a transform. |
| inverseType | Type to guarantee when doing a transformInverse. |
Collection
Container Any[] <==> Any[]Apply a transformer to a collection of values.
// Applies the `Primitive` transformer to each item of the array
Collection(Primitive())
| Option | Description |
|---|---|
| transformer | The transformer to apply to each items of the collection. Default is Raw(). |
Raw
Value Any <==> AnyPlaceholder transformer doing nothing. Used when a transformer is always required but no processing should be done.
Model
Value Model <==> AnyThis transform is kind of special. It doesn't transform anything itself, but it calls the TransformService
so it can execute the same root transformer that is currently in use, making the transform recursive.
This transformer doesn't take any parameter, it relies on the context to know what to do.
You use it like this:
class Sub {
@Pojo()
public foo: string = 'default';
}
class Foo {
@Pojo(Model())
@Relation(Sub)
public sub: Sub = new Sub();
}
NOTE
In the example above, there is a big difference if we omit the Model() transformer:
class Sub {
@Pojo()
public foo: string = 'default';
}
class Foo {
@Pojo()
@Relation(Sub)
public sub: Sub = new Sub();
}
In this case, the result will be:
{"sub": "[object Object]"}
This is because the default transformer of @Pojo is Primitive, that cast the object into a String.
You could do:
class Sub {
@Pojo()
public foo: string = 'default';
}
class Foo {
@Pojo(Raw())
@Relation(Sub)
public sub: Sub = new Sub();
}
In which case you would keep the Sub instance as is.
But if you want to transform it to an object literal, like you do for Foo, you have to give it a Model() transformer so
the root transformer Pojo can run again.