Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make an API call in Angular 2?

Tags:

http

angular

There are lots of resources out there already but I haven't been able to find one that works for one reason or another. Take a generic example: I want to get the response from http://swapi.co/api/people, which will be a list of people from Star Wars.

import {Injectable } from '@angular/core';
import {Http, Response} from '@angular/http';
import {Observable} from 'rxjs/Observable';

import 'rxjs/add/operator/map';

@Injectable()
export class OombaDataService {
    constructor(private http: Http) {}
    private usersUrl = 'http://swapi.co/api/people/';

    getData() {
        return this.http.get(this.usersUrl)
        .map(this.extractData)
    }

    private extractData(res: Response) {
        let body = res.json();
        return body.data || { };
    }
    private handleError (error: any) {
      // In a real world app, we might use a remote logging infrastructure
      // We'd also dig deeper into the error to get a better message
      let errMsg = (error.message) ? error.message :
                   error.status ? `${error.status} - ${error.statusText}` : 'Server error';
      console.error(errMsg); // log to console instead
      return Observable.throw(errMsg);
    }
}

A lot of this should be correct since it's based on Angular's own tutorial on the matter. But for whatever reason, when I call it in my components, it just returns an observable object without the JSON data. What am I missing?

like image 320
Daniel Avatar asked Apr 08 '26 09:04

Daniel


1 Answers

At this method:

private extractData(res: Response) {
    let body = res.json();
    return body.data || { };
}

At the first line, you parse the result of the API call as JSON into a JavaScript object. Then you return the property data of that object, if it exists. If it doesn't exist, you return an empty object ({ }).

The thing is that the API at http://swapi.co/api/people/ does not bring a response that contains a data property, which means that the extractData() method is always returning an observable of an empty object ({ }).

Besides that, the getData() really returns an Observable, so to get its value, you must subscribe to it, such as:

@Component({
  ...
  providers: [OombaDataService]
})
export class SomeComponent {

  constructor(oombaDataService: OombaDataService) {
    oombaDataService.getData().subscribe(
      x => {
          console.log("VALUE RECEIVED: ",x);
      },
      x => {
          console.log("ERROR: ",x);
      },
      () => {
          console.log("Completed");
      }
    );
  }

}

And, since, as said, that API's response does not have any .data property in it, the extractData() should really be (at least until you figure out what you want):

private extractData(res: Response) {
    return res.json();
}

That should get things working. Here's a working plunker.

like image 169
acdcjunior Avatar answered Apr 10 '26 21:04

acdcjunior