1

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>
5
  • Did you check what value res.json() actually returns. It doesn't look like it is an array. Your cast is meaningless at runtime. That's only for static analysis. Commented Oct 4, 2016 at 16:30
  • @GünterZöchbauer Yes, I've checked and it is working in my other component we I'm just displaying the list of departments and their description Commented Oct 4, 2016 at 16:37
  • Try adding {{departments | json }} to the template instead of the *ngFor and ensure it displays an array. Commented Oct 4, 2016 at 16:38
  • @GünterZöchbauer It returns: [ { "id": 1, "name": "Backend", "description": "Back End Developers." }, { "id": 55, "name": "Test for Bin", "description": "CAN BE DELETED" }, { "id": 66, "name": "bbb", "description": "aaa" }, { "id": 67, "name": "Test for Joe", "description": "CAN BE DELETED" }, { "id": 69, "name": "sdfsdfs", "description": "Common Development Services" }, { "id": 74, "name": "New", "description": "New dep" } ] Commented Oct 4, 2016 at 16:46
  • can you tell us what departments object contains? Commented Oct 4, 2016 at 16:50

2 Answers 2

2

Use a different name for

#departments="ngModel"

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

Sign up to request clarification or add additional context in comments.

Comments

0

Try changing type

public departments: Array<any> = [];

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

1 Comment

the same error_handler.js:45 EXCEPTION: 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.