Nick Hodges
Nick Hodges

Reputation: 17138

Why doesn't my data binding bind in Angular 2?

I am an Angular 2 newbie whose Google-Fu has failed him for three days now.

This is going to be hard to explain, so I'll do my best.

I have a class that looks like this:

import { Component } from '@angular/core';
import { Brush, BrushService } from '../services/brush.services';

@Component({
  selector: 'brush-body',
  templateUrl: './brushbody.html'
})
export default class BrushBodyComponent{

  brushes: Brush[] = [];

  constructor(private brushService: BrushService) {
    this.brushService.getBrushes().subscribe(
                  (data: any) => {
                  if (Array.isArray(data)){
                    this.brushes = <Brush[]>data;
                     }
                  },
                  (err: any) => console.log('Cannot get brushes.  Error code %s, URL: %s', err.status, err.url),
                  () => console.log('Brush(es) were retrieved. Here they are: ', this.brushes));

  }

}

The TemplateURL is this:

<div class="row">
  <div *ngFor="let brush of brushes">
    <brush-panel  [brush]="brush"></brush-panel>
  </div>
</div>

The problem is the brush isn't getting any values - it is always undefined.

I am 100% certain that the getBrushes() call above is working, as I can see the data in the console.

I'm trying to display the data with this class:

import { Component, Input } from '@angular/core';
import { Brush } from '../services/brush.services';


@Component({
  selector: 'brush-panel',
  templateUrl: './brushpanel.html'
})
export default class BrushMainComponent {
   @Input() brush: Brush;
}

and this HTML:

  <div>
        <div class="panel panel-info">
          <div class="panel-heading">
            <a [routerLink]="['/brushes', brush.id]"> {{brush.body}}:  {{ brush.title }} </a>
          </div>  
          <div class="panel-body">
            {{ brush.description }}
          </div>
          <div class="panel-footer">
              <brush-stars [rating]="brush.rating"></brush-stars>
          </div>
        </div>
  </div>

However, all I get are empty bootstrap panels.

I am at a complete loss as to why.

Thanks in advance.

Added:

Here is the service:

@Injectable()
export class BrushService {

  constructor(private aHttpService: Http){}

  getBrushes(): Observable<Brush[]>{
      return this.aHttpService
      .get('http://localhost:15182/api/brush')
      .map(response => response.json());
      }

  getBrushById(brushId: number): Brush {
    let result: Brush = null;
    this.aHttpService.get('http://localhost:15182/api/brush/${brushId}').map(response => response.json())
    .subscribe((data: Brush) => {
                  result = data;
                  },
                  (err: any) => {
                                  console.log('Cannot get products.  Error code %s, URL: %s', err.status, err.url);
                                  result = null;
                                },
                  () => {
                          console.log('Brush(es) were retrieved');
                          result = null;
                        }
    )
    return result;
  }

  getCommentsForBrush(brushId: number): Comment[] {
      let c: Comment[] = [];
      this.aHttpService
      .get('http://localhost:15182/api/brush/${brushId}/comments')
      .map((response: any) => response.json())
      .map((comments: any) => comments.map((c: any) => new Comment(c.id, c.brushId, new Date(c.timestamp), c.user, c.rating, c.comment))
      .subscribe((data: any) => {
                  if (Array.isArray(data)){
                    c = data;
                    }
                  },
                  (err: any) => console.log('Cannot get comments.  Error code %s, URL: %s', err.status, err.url),
                  () => console.log('Comment(s) were retrieved')));

    return c;
  }
}

Here is the class for the Brush:

export class Brush {
  constructor(
      public id: number,
      public title: string,
      public rating: number,
      public celebrity: string,
      public description: string) {
      }
  }

Here is a single JSON record:

{
Id: 0,
Title: "Met her at the grocery",
Rating: 1,
Celebrity: "Taylor Swift",
Description: "Saw Taylor Swift at the grocery store. Said hello. Took a picture. She was really nice."
},

Upvotes: 0

Views: 187

Answers (2)

Nick Hodges
Nick Hodges

Reputation: 17138

The answer was simple: The JSON had initial capitals on the fields. My template had lower case. Once I matched up the case in the template with the case of the JSON, it all worked as exactly as expected.

Upvotes: 0

Suneet Bansal
Suneet Bansal

Reputation: 2702

I suspect that Array.isArray() returns false since data is not an array.

Check whether code control comes inside if (Array.isArray(data)){ } block.

Upvotes: 1

Related Questions