Transformers and Validators
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}
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.