1

I'm trying to bind json data to template, but I keep getting some exceptions. Here's my code:

account.ts

export interface Account{
    AccountType:string;
    AmountHeld:string;
    AvailableBalance:string;    
}

account.service.ts

import { Injectable, Inject } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import { Http, Headers, RequestOptions, Response } from '@angular/http';
import {Account} from '../models/account';
import { Cookie } from 'ng2-cookies/ng2-cookies';

const URL = "http://payd.azurewebsites.net/api/User/1/account";

const AUTH = Cookie.get('token');

@Injectable()
export class AccountService {

  private accounts;

  constructor(private http: Http) {

  }

  httpGet(): Observable<Account> {
  var headers = new Headers();
  headers.append('Authorization', 'bearer ' + AUTH);
  //headers.append('Content-Type', 'application/x-www-form-urlencoded');

  return this.http.get(URL, {
     headers: headers
  }).map((response: Response) => response.json());
 }
}

account.component.ts

import { Component, OnInit } from '@angular/core';
import {AccountService} from '../services/account.service';
import { HttpClient } from '../providers/http-client';
import {Account} from '../models/account';

@Component({
  selector: 'app-account',
  templateUrl: './account.component.html',
  //styleUrls: ['./account.component.css'],
})
export class AccountComponent implements OnInit {

  private accounts:Account;
  private AccountType;
  private AmountHeld;
  private AvailableBalance;

  constructor(private _service:AccountService) {

  }

  ngOnInit() {    
    this._service.httpGet().subscribe(accounts=>{
      this.accounts=accounts;
    });
  }
}

account.component.html

<ul>
  <li>
    {{accounts.AccountType}}
  </li>
</ul>

I successfully get json respose, I can see it in browser tools. But, when I try to bind data to template, I get this error:

EXCEPTION: Uncaught (in promise): Error: Error in ./AccountComponent class AccountComponent - inline template:9:6 caused by: self.context.accounts is undefined`.

I'm new to Angular 2, any help is appreciated. Thanks in advance!

Stefan Svrkota
  • 48,787
  • 9
  • 98
  • 87
Isuru
  • 950
  • 1
  • 13
  • 34

2 Answers2

1

You have to use *ngIf directive or Elvis operator (?) to "protect" your template until data is loaded from web API.

*ngIf directive

<ul *ngIf="accounts">
  <li>
      {{accounts.AccountType}}
  </li>
</ul>

Elvis (?) operator

<ul>
  <li>
      {{accounts?.AccountType}}
  </li>
</ul>

You are getting current error because you are trying to display accounts.AccountType while accounts variable is undefined (hasn't received data from web API yet).

Stefan Svrkota
  • 48,787
  • 9
  • 98
  • 87
  • 1
    Thank you very much. Yes it works now. I would like to know that whenever we are calling a get api do we have to use `ngIf directive` or `Elvis (?)` operators in template since there will always be a delay when populating a response via api? – Isuru Oct 18 '16 at 11:16
  • 1
    @Isuru There are other ways to do this, but this is usually the way it is done. First other way that comes to my mind is to dynamically add html from component to template after you get response web API. This can be done using `ElementRef`. – Stefan Svrkota Oct 18 '16 at 11:22
  • 1
    Ok i understood. I'll be researching about that more. Thanks! – Isuru Oct 18 '16 at 11:25
0

You can use resolve property of RouterModule comes with new @angular/router": "3.0.0" package.

Route component will be loaded after you will get JSON data via API.

{ 
  path: ':id',
  component: CrisisDetailComponent,
  resolve: {
     crisis: CrisisDetailResolve
  }
}

check Angular Example - Router for implementation.

Hope that helps!

Satendra
  • 6,755
  • 4
  • 26
  • 46