En este artículo hablaremos de la utilización de un mapper creado con anterioridad en este blog combinándolo con la tecnología de los observables en Angular.

Básicamente consistirá en llamar al mapper cuando se invoque al operador ‘map’ de los observables para mapear o bien un array o una única entidad.

Uso

Antes que nada, importaremos las diferentes clases y operadores para los ejemplos de la librería ‘rxjs’ de la siguiente manera:

import { Observable, of, from } from 'rxjs';
import { map } from 'rxjs/operators';

Y creamos el array de objetos a mapear:

this.readEntities = [
            {
                id: '1',
                name: 'example mapper',
                birthDate: '2000/01/01',
                type: 'person',
                version: 1
            }
            , {
                id: '2',
                name: 'example mapper 2',
                birthDate: '2000/01/01',
                type: 'person2',
                version: 2
            }
        ];

Operador of

Para el ejemplo de mapear todo un array, utilizaremos el operador ‘of’ sobre un array para obtener un observable de todo el array. Luego con el operador ‘map’ (dentro del pipe) podremos invocar a nuestro mapper de la siguiente manera en nuestro archivo typescript del componente:

const readEntitiesOf$: Observable<Array<IReadEntity>> = of(this.readEntities);
       
        this.entitiesOf$ = readEntitiesOf$
        .pipe(
            map(
            (readEntity: Array<IReadEntity>) => 
                this._entityMapperService.transform(readEntity)
            )); 

Simplemente para visualizar el resultado en el html:

 {{ arrayEntitiesOf$ | async | json }}

Operador from

Para crear un observable y que vaya entregando cada objeto del array, usaremos el operador ‘from‘.

const arrayReadEntitiesFrom$: Observable<IReadEntity> = from(this.readEntities);

Finalmente cada vez que nos llegue un objeto lo mapearemos y lo añadiremos a una lista de la siguiente manera:

 arrayReadEntitiesFrom$.pipe(map((readEntity: IReadEntity) =>
            this._entityMapperService.transform(readEntity)
        ))
        .subscribe((value: IEntity) => this.entitiesFrom.push(value));

El código para visualizarlo en el html:

<div *ngFor="let entity of entitiesObs; trackBy:entityId">
    {{ entity | json }}
</div>

Ahora bien, como vamos añadiendo objetos al array cada vez que se entrega, usaremos el trackBy del *ngFor para tener un mejor rendimiento:

public entityId(index: number, entity: IEntity): string {
    return entity.id;
}

Conclusiones

Como puede verse, el mapper creado en artículo anterior «Mapper en typescript» se puede usar tanto para una entidad como para un array dentro del operador ‘map’ de los observables. Esto nos permite seguir manteniendo la responsabilidad del mapeo separada en una clase.

Puedes descargar el código del artículo en GitHub