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 <==> String

The 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 literal

The 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 <==> FormObject

The 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 <==> Primitive

Ensure 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 <==> Any

Placeholder transformer doing nothing. Used when a transformer is always required but no processing should be done.


Model

Value Model <==> Any

This 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.