0

This is my Interface / Type

export interface Employee {
  id: number;
  name: string;
}
export type EmployeesMap = Map<number, Employee>;

This is my Service

class EmployeeService {
  employees$: Observable<Employee[]> = of([
    {
      id: 1,
      name: 'Joe',
    },
    {
      id: 2,
      name: 'Mel',
    },
  ]);
  employeesMap$: Observable<EmployeesMap> = this.employees$.pipe(
    map((employees) => {
      const map: [number, Employee][] = employees.map((employee) => [
        employee.id,
        employee,
      ]);
      const employeeMap: EmployeesMap = new Map(map);
      return employeeMap;
    })
  );
}

This is my Child Component

@Component({
  selector: 'app-child',
  standalone: true,
  imports: [CommonModule],
  template: `{{employees | json}}<br>{{employeesMap | json}}`,
})
export class ChildComponent {
  @Input() employees: Employee[] = [];
  @Input() employeesMap: EmployeesMap = new Map();
}

This is my Parent Component

@Component({
  selector: 'my-app',
  standalone: true,
  imports: [CommonModule, ChildComponent],
  template: `
    <h1>Hello from Angular!</h1>
    <app-child 
      <!-- THIS WORKS... -->
      [employees]="(employees$ | async) ?? []" 
      <!-- THIS ERRORS... -->
      [employeesMap]="(employeesMap$ | async) ?? {}"
    />
  `,
})

Stackblitz: https://stackblitz.com/edit/stackblitz-starters-mhjnga?file=src%2Fmain.ts

I get the following error: Type 'EmployeesMap | {}' is not assignable to type 'EmployeesMap' Type '{}' is missing the following properties from type 'Map<number, Employee>': clear, delete, forEach, get, and 8 more.

Appreciate any help

Easton
  • 3
  • 3
  • 2
    Don't post image of code. Paste your code as text. – Ricky Mo Aug 21 '23 at 02:31
  • 1
    A quick resolve will be `employeesMap` input parameter to support empty object `@Input() employeesMap: EmployeesMap | {} = new Map();` – Yong Shun Aug 21 '23 at 02:33
  • @Ricky apologies, this is my first post, I only realised it after posting. I've removed the image and posted the code as text. Got replica of the problem on Stackblitz (Link above). – Easton Aug 21 '23 at 03:29
  • @YongShun The error goes away but I get back an empty object, the async pipe still wasn't able to pipe the data thru, any advice – Easton Aug 21 '23 at 03:38
  • I don't think it is the issue came from `async` pipe, but you can't `JSON.stringify()` the `Map`. For your reference: https://stackoverflow.com/q/29085197/8017690 – Yong Shun Aug 21 '23 at 08:23

1 Answers1

0

In order to render map values you need to use its keys or values iterators. So, in your child component replace the template with e.g. the following:

template: `employees: {{employees | json}}<br>employeesMap: <div *ngFor="let key of employeesMap?.keys()">{{ key }}, {{ employeesMap?.get(key)?.name }}</div>`

And in the class say:

@Input() employeesMap: EmployeesMap | null = new Map();

And in the parent component:

 <app-child 
      [employees]="(employees$ | async) ?? []" 
      [employeesMap]="employeesMap$ | async"
    />
Benny Halperin
  • 1,872
  • 3
  • 13
  • 18
  • this solved my problem, didn't know that we cannot pass map objects like normal arrays, learn something new today, Thanks :-) – Easton Aug 21 '23 at 18:49