
En muchas ocasiones necesitamos escribir cadenas de texto en las plantillas de Angular.
Las dos soluciones más habituales (o al menos las que he visto en los proyectos en los que he trabajado) son:
- Escribir el valor de la variable directamente en la plantilla:
foo-component.component.html
<img [src]="'path/to/my/resource.png'">
<div> THIS IS A FOO TITLE </div>
Esta forma tiene el problema de que las constantes no están unificadas y, si más adelante quieres cambiar esos valores, tendrás que buscar los literales y sustituirlos uno a uno.
- Escribir las constantes en un archivo aparte, importarlas y declararlas como variables en el componente para usarlas:
my-collection-of-constants.ts
export const Foo = {
foo: 'foo',
resource: 'my/foo/file.png'
}
my-component.component.ts
@Component(
...
)
export class MyComponent {
public foo = Foo;
...
public getFooValueByKey(key: string) {
return this.foo[value];
}
}
my-component.component.html
<div> {{ getFooValueByKey('foo') }} </div>
<img [src]="foo.resource">
Con esta solución unificamos el valor de las constantes, ¡bien!.
Sin embargo, ensuciamos el componente con muchas variables y métodos cuya única función es mostrar texto.
Solución propuesta: usar pipes
Para evitar hardcodeo en plantillas y declarar variables innecesarias en los componentes, propongo lo siguiente basado en pipes de Angular:
- Generar un archivo con un objeto que contenga los valores a usar o mostrar:
hardcoded-values.ts
export const hardcodedValues = {
pasta: 'An awesome pasta dish',
pizza: 'The most tasty pizza ever',
dessert: 'Icecream, cupcakes... and more!'
}
- Crear el pipe de la siguiente forma.
prevent-hardcoding.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
import { hardcodedValues } from './hardcoded-values.ts';
@Pipe({
name: 'preventHardcoding'
})
export class PreventHardcodingPipe implements PipeTransform {
transform(value: any, args?: any): any {
if (value in hardcodedValues) {
return hardcodedValues[value];
} else {
console.error(
`
No properly value set for key '${value}'.
Please, check available keys.
Feel free to add new one if you need.
`
);
return undefined;
}
}
}
Si miras el método transform, lo que hace es comprobar si existe la clave y, si es así, devolver el valor asociado.
¡Perfecto! Ya podemos usar el pipe para leer los valores del objeto hardcodedValues.
app.component.html
<!-- Display value in template -->
<div> {{ 'pasta' | preventHardcoding }} </div>
<!-- As @Input for component -->
<app-foo
[someInput]="'pizza' | preventHardcoding">
</app-foo>
Con este patrón desacoplamos el valor de las cadenas, números, etc. de cada componente. Así, cualquier cambio en el objeto de valores se propagará a todos los componentes que usen el pipe preventHardcoding.
prevent-hardcoding-pipe - StackBlitz
Publicado originalmente en dev.to.