[ngx-formly] Use Angular Formly Extensions to automatically localize all field labels
In this lesson we're diving a bit deeper and learn how to inject services into Formly Extensions with the example of using ngx-translate to localize all of our form field labels.
Create Extension with Tranlsate service:
// translate.extension.ts import { TranslateService } from '@ngx-translate/core'; import { FormlyFieldConfig } from '@ngx-formly/core'; export class TranslateExtension { constructor(private translate: TranslateService) {} prePopulate(field: FormlyFieldConfig) { const to = field.templateOptions || {}; if (!to.label || to._translated) { return; } to._translated = true; field.expressionProperties = { ...(field.expressionProperties || {}), 'templateOptions.label': this.translate.stream( field.templateOptions.label ) }; } } export function registerTranslateExtension(translate: TranslateService) { return { extensions: [ { name: 'translate-extension', extension: new TranslateExtension(translate) } ] }; }
Define in module:
import { registerTranslateExtension } from './translate.extension'; // AoT requires an exported function for factories export function HttpLoaderFactory(httpClient: HttpClient) { return new TranslateHttpLoader(httpClient, 'assets/i18n/', '.json'); } export function minValidationMessage(err, field: FormlyFieldConfig) { return `Please provide a value bigger than ${err.min}. You provided ${err.actual}`; } export function ipValidationMessage(err, field: FormlyFieldConfig) { return `"${field.formControl.value}" is not a valid IP address`; } export function IpValidator(control: FormControl): ValidationErrors { return !control.value || /(\d{1,3}\.){3}\d{1,3}/.test(control.value) ? null : { ip: true }; } @NgModule({ declarations: [AppComponent, NgSelectFormlyComponent], imports: [ BrowserModule, SharedModule, AppRoutingModule, BrowserAnimationsModule, ReactiveFormsModule, NgSelectModule, HttpClientModule, TranslateModule.forRoot({ loader: { provide: TranslateLoader, useFactory: HttpLoaderFactory, deps: [HttpClient] } }), FormlyModule.forRoot({ validators: [ { name: 'ip', validation: IpValidator } ], validationMessages: [ { name: 'required', message: 'This field is required' }, { name: 'min', message: minValidationMessage }, { name: 'ip', message: ipValidationMessage } ], types: [ { name: 'my-autocomplete', component: NgSelectFormlyComponent } ], extensions: [ { name: 'data-cy- extension', extension: dataCyExtension } ] }), FormlyMaterialModule ], providers: [ { provide: FORMLY_CONFIG, multi: true, useFactory: registerTranslateExtension, deps: [TranslateService] } ], bootstrap: [AppComponent] }) export class AppModule {}