Transformers and Validators

Custom Transformers

On top of the built-in transformers, you can add your own transformers so that you can auto-heal and format data based on your requirements. To do this you will need to name your transformer and associate it with a callback to be called every time it is used. You can add as many transformers as necessary.

1{
2 "transformers": {
3 "my-transformer": function(record, field) {
4 ...
5 },
6 "my-transformer-with-single-arg": function(record, field, arg1) {
7 ...
8 },
9 "my-transformer-with-multiple-args": function(record, field, arg1, arg2, arg3) {
10 ...
11 }
12 }
13}

Let's see how we can add a transformer called phone to reformat phone numbers using the google-libphonenumber library. Please note that you cannot overwrite a transformer that already exists and you will get an error if you try to do that.

1{
2 "transformers": {
3 "phone": function (record, key) {
4 const value = record.get(key);
5 try {
6 const parsedValue = parsePhoneNumberWithError(value, {
7 defaultCountry: 'US'
8 });
9 if (!parsedValue.isValid()) {
10 return value;
11 }
12 
13 if (parsedValue.country === defaultCountry) {
14 return parsedValue.formatNational();
15 }
16 
17 return parsedValue.formatInternational();
18 } catch (e) {
19 return value;
20 }
21 }
22}

That's all! You can use the pipe syntax to use the new transformer.

1{
2 "fields": [
3 {
4 "label": "First name",
5 "transformers": "trim"
6 },
7 {
8 "label": "Last name",
9 "transformers": "trim"
10 },
11 {
12 "label": "Phone",
13 "transformers": "trim|phone"
14 },
15 {
16 "label": "Email",
17 "transformers": "trim"
18 }
19 ]
20}

Passing additional arguments

Transformers can be made more dynamic by accepting additional arguments. Let's enhance our example to accept a country code as the first argument. If no argument is provided we will default to US.

1{
2 "transformers": {
3 "phone": function (record, key, defaultCountry) {
4 const value = record.get(key);
5 try {
6 const parsedValue = parsePhoneNumberWithError(value, {
7 defaultCountry: defaultCountry || 'US'
8 });
9 if (!parsedValue.isValid()) {
10 return value;
11 }
12 
13 if (parsedValue.country === defaultCountry) {
14 return parsedValue.formatNational();
15 }
16 
17 return parsedValue.formatInternational();
18 } catch (e) {
19 return value;
20 }
21 }
22}

You can now pass the country code as indicated below.

1{
2 "fields": [
3 {
4 "label": "First name",
5 "transformers": "trim"
6 },
7 {
8 "label": "Last name",
9 "transformers": "trim"
10 },
11 {
12 "label": "Phone",
13 "transformers": "trim|phone:UK"
14 },
15 {
16 "label": "Email",
17 "transformers": "trim"
18 }
19 ]
20}

Similarly, you can add custom validators.