0

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?

1 Answer 1

2

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

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

1 Comment

Dave, thanks for the response, I didn't know about the "?" feature in templates (still pretty new to Angular), that's good to know. What you're saying makes sense as auth_info is "fed" by an asynchronous function call, I was (mistakenly) under the impression that using an Observable took care of that. Again, thanks for the helpful response!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.