antonyboom antonyboom - 2 months ago 49
TypeScript Question

Cannot find a differ supporting object '[object Object]' of type, Angular 2

I'm newbie in Angular 2 and trying to write a simple ng-form following by official tutorial.
If I'm using simple array from tutorial, it works fine:

powers = ['Really Smart', 'Super Flexible',
'Super Hot', 'Weather Changer'];


But when I'm changing it on my custom array from http

public departments = [];

constructor(http: Http) {
http.get('/api/departments')
.map((res: Response) => res.json())
.subscribe((departments: Array<Object>) => this.departments = departments);
}


I'm getting an error:


error_handler.js:51 Error: Uncaught (in promise): Error: Error in ./AddClientComponent class AddClientComponent - inline template:41:12 caused by: Cannot find a differ supporting object '[object Object]' of type 'departments'. NgFor only supports binding to Iterables such as Arrays.


So where is my mistake and what am I missing? thanks in advance.

AddClientComponent

import 'rxjs/add/operator/map';

import {Component} from '@angular/core';
import {Http, Response} from '@angular/http';

import { DepartmentsComponent } from '../departments/departments.component';

@Component({
selector: 'app-add-client',
templateUrl: './add-client.component.html',
styleUrls: ['./add-client.component.css']
})

export class AddClientComponent {

public departments = [];
public firstName = '';
public lastName = '';
public id = null;

constructor(http: Http) {
http.get('/api/departments')
.map((res: Response) => res.json())
.subscribe((departments: Array<Object>) => this.departments = departments);
}

model = new Employee(
this.id,
this.firstName,
this.lastName,
this.departments
);

submitted = false;

onSubmit() { this.submitted = true; }

active = true;

}

export class Employee {
constructor(
public id: number,
public firstName: string,
public lastName: string,
public departments: any
) { }
}


html

<div class="container">
<div [hidden]="submitted">
<h1>Employee Form</h1>
<form *ngIf="active" (ngSubmit)="onSubmit()" #employeeForm="ngForm">

<div class="form-group">
<label for="firstName">First Name</label>
<input type="text" class="form-control" id="firstName"
required
[(ngModel)]="model.firstName"
name="firstName"
#firstName="ngModel" >

<div [hidden]="firstName.valid || firstName.pristine"
class="alert alert-danger">
First Name is required
</div>
</div>

<div class="form-group">
<label for="lastName">Last Name</label>
<input type="text" class="form-control" id="lastName"
required
[(ngModel)]="model.lastName"
name="lastName"
#lastName="ngModel" >

<div [hidden]="lastName.valid || lastName.pristine"
class="alert alert-danger">
Last Name is required
</div>
</div>

<div class="form-group">
<label for="departments">Department</label>
<select class="form-control" id="departments"
required
[(ngModel)]="model.departments"
name="departments"
#departments="ngModel" >
<option
*ngFor="let department of departments"
[value]="department">{{department.name}}
</option>
</select>

<div [hidden]="departments.valid || departments.pristine"
class="alert alert-danger">
Department is required
</div>
</div>

<button type="submit"
class="btn btn-default"
[disabled]="!employeeForm.form.valid">Submit
</button>
<!--<button type="button"-->
<!--class="btn btn-default"-->
<!--(click)="newHero()">New Hero-->
<!--</button>-->
</form>
</div>

<div [hidden]="!submitted">
<h2>You submitted the following:</h2>
<div class="row">
<div class="col-xs-3">First Name</div>
<div class="col-xs-9 pull-left">{{ model.firstName }}</div>
</div>
<div class="row">
<div class="col-xs-3">Last Name</div>
<div class="col-xs-9 pull-left">{{ model.lastName }}</div>
</div>
<div class="row">
<div class="col-xs-3">Department</div>
<div class="col-xs-9 pull-left">{{ model.departments }}</div>
</div>
<br>
<button class="btn btn-default" (click)="submitted=false">Edit</button>
</div>
</div>

Answer

Use a different name for

#departments="ngModel"

I think it overloads the departments property of the class used in *ngFor

Comments