简体   繁体   中英

Angular 9 Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays

I am using async pipe in my template for an Observable:

applicants$: Observable<UserProfile[]>;
  ngOnInit() {
    this.applicants$ = this.store.pipe(
      select(fromRootUserProfileState.getUserProfiles)
    ) as Observable<UserProfile[]>;
}

Here is UserProfile.ts interface:

import { Role } from './role/role';
import { Country } from './Country';

export interface UserProfile {
  id?: number;
  fullName?: string;
  roles?: Role[];
  windowsAccount?: string;
  firstName?: string;
  lastName?: string;
  email?: string;
  managerName?: string;
  managerId?: number;
  managerEmail?: string;
  companyId?: number;
  companyName?: string;
  countryId?: number;
  country?: Country;
  countryName?: string;
}

And here is the userProfile.service

  getUserProfiles(): Observable<UserProfile[]> {
    return this.http.get<UserProfile[]>(
      this.baseUrl + 'userprofiles/getuserprofiles'
    );
  }

In the template I've used ngFor to iterate through the Observable with an async pipe:

<mat-form-field
  fxFlex="22"
  appearance="outline"
  *ngIf="applicants$ | async as applicants"
>
  <mat-label>Applicant</mat-label>
  <mat-icon matPrefix>person</mat-icon>
  <mat-select
    placeholder="Applicant"
    name="applicant"
    [(ngModel)]="this.searchPurchaseOrder.applicantId"
  >
    <mat-option *ngFor="let ap of applicants" [value]="ap.id">
      ap.fullName
    </mat-option>
  </mat-select>
</mat-form-field>

However, here is the error I am getting: 在此处输入图像描述

Here is the data shape from the store. It is being populated, so there is no problem there: 在此处输入图像描述

You will need to use the keyvalue pipe to loop through your object as if it were an array.

https://angular.io/api/common/KeyValuePipe

<div *ngFor="let applicant of applicants | keyvalue">
  {{applicant.key}}:{{applicant.value}}
</div>

This can work with the async pipe too, eg:

<div *ngFor="let item of (object$ | async) | keyvalue">

The problem here is that you are trying to use ngFor to loop through an object (Which is not possible). If you can post a preview of the response from the network tab it would be helpful to get a better idea about the matter.

Thanks to Matt Saunders ' answer this change to the template has worked for my case:

<mat-form-field
  fxFlex="22"
  appearance="outline"
  *ngIf="this.applicants$ | async | keyvalue as applicants">
  <mat-label>Applicant</mat-label>
  <mat-icon matPrefix>person</mat-icon>
  <mat-select
    placeholder="Applicant"
    name="applicant"
    [(ngModel)]="this.searchPurchaseOrder.applicantId">
    <mat-option
      *ngFor="let applicant of applicants"
      [value]="applicant.value.id">
      {{ applicant.value.fullName }}
    </mat-option>
  </mat-select>
</mat-form-field>

Try using the pipe with the alias also: let ap of applicants | async let ap of applicants | async .

Well if you getting the data from backend..... Like node Mongo then follow this approach

res.status().json({ data: [yourdata] })

Now you don't need to do anything.

Happy codding.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM