angularrxjsangular-http

Angular 2 HTTP service problems


I'm working with Angular 2.1.0 and am having problems trying to create an HTTP service to call a REST API provided by my server. I've looked around a lot using Google, and read many articles about how to do this, but I've goofed something up.

Here is the problem, it looks like my HTTP service is running correctly and getting the data from the REST API. My component subscribes to the observable returned by the service, but the data never gets assigned to the component variable, and my template blows up saying I'm trying to get an attribute from NULL.

Here is my service code:

import { Injectable } from '@angular/core';
import { Http, Response, URLSearchParams } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';

import { AuthInfoInterface } from '../interfaces/authentication';

@Injectable()
export class AuthenticationService {
  private url: string = 'api/authentication';

  constructor (private http: Http) {}

  get(): Observable<AuthInfoInterface> {
    let params = new URLSearchParams();

    params.set("redirect", "false");
    params.set("passive", "true");
    return this.http.get(this.url, {search: params})
      .map((res: Response) => res.json())
      .catch(this.handleError);
  }
  handleError(error: any) {
    let errorMsg = error.message || 'Server Error!';
    console.error(errorMsg);
    return Observable.throw(errorMsg);
  }
}

And here is my component code:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';
import { AuthenticationService } from '../services/authentication.service';
import { AuthInfoInterface } from '../interfaces/authentication';

@Component({
  selector: 'authentication',
  templateUrl: 'authentication.component.html',
  styleUrls: ['authentication.component.scss'],
  providers: [AuthenticationService]
})
export class AuthenticationComponent implements OnInit, OnDestroy {
  showLogin: boolean = true;
  auth_info: AuthInfoInterface;
  subscription: any;

  constructor(private authenticationService: AuthenticationService) {
  }
  getAuthentication() {
    this.subscription = this.authenticationService.get()
      .subscribe(
        auth_info => this.auth_info = auth_info,
        err => console.error('Error: ' + err)
      );
  }
  ngOnInit() {
    this.getAuthentication();
  }
  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

And here is my simplified template code:

  <div>
    {{auth_info.auth_displayname}}
  </div>

What can I try to resolve this?


Solution

  • You need to allow auth_info to be null, since the http call is asynchronous. You can do that by adding an *ngIf before the place where you bind the property to the template or by adding a ? to the property name: auth_info?.auth_displayname