Búsqueda de sitios web

MapToIterable en un pipe de Angular con TypeScript


Intentando implementar un pipe en Angular. Después de darme cuenta de que ngFor no funcionaría con mapas. Algunas investigaciones me llevaron a creer que se estaban por venir funciones futuras para lidiar con eso, pero mientras tanto, un pipe mapToIterable era la respuesta.

Tengo el siguiente código:

import {Pipe, PipeTransform} from '@angular/core';

@Pipe({
  name: 'mapToIterable'
})
export class MapToIterablePipe implements PipeTransform  {
  transform(map: Map<string, Object>, args: any = []): any {
    const a: any[] = [];
    console.log(map.keys());  // <- works as expected
    for (const k in map) {
      if (map.has(k)) {
        console.log("hello");  // <- never executes
        console.log(k);
        a.push({key: k, val: map.get(k)});
      }
    }
    console.log(a); // <- always empty
    return a;
  }
}

export const MAPTOITERABLE_PROVIDERS = [
  MapToIterablePipe
];

map.keys() me da una lista de claves correctas, pero nada más funciona.

¿Alguna sugerencia sobre cómo diagnosticar por qué mi bucle no está llenando correctamente el arreglo?

Respuesta #1

Las 'keys' de Map no son claves de objeto y no se pueden obtener con Object.keys() ni con el operador in.

Considerando que map.keys() devuelve un iterable, debería ser

for (const key of Array.from(map.keys())) {
  // this check is unneeded
  // if (map.has(k)) {
  ...
}

O en TypeScript 2.3 con la opción downlevelIteration,

for (const key of map.keys()) { ... }

O solo

const a: any[] = Array.from(map.entries()).map(([key, val]) => ({ key, val }));

Debido a cómo TypeScript implementa el operador spread, [...iterable] no funcionará de la misma manera que Array.from(iterable) en la versión 2.2 y anteriores.