1

Some questions are also provided in the code comments.

code:

import { Injectable } from '@angular/core';
import { Http, Headers } from '@angular/http';
import 'rxjs/add/operator/map';

@Injectable()
export class Reviews {

  data: any;

  constructor(public http: Http) {
    this.data = null;
  }

  getReviews(){

    if (this.data) {
      return Promise.resolve(this.data);//what is the use of this promise here?
    }

    return new Promise(resolve => {

      this.http.get('http://localhost:8080/api/reviews')
        .map(res => res.json())        //do we use .map operator in observables only? also the subscribe function? do we not use here .then?
        .subscribe(data => {         
          this.data = data;
          resolve(this.data);
        });
    });

  }

  createReview(review){

    let headers = new Headers(); // what is the use of headers here?When do we use these headers?
    headers.append('Content-Type', 'application/json');

    this.http.post('http://localhost:8080/api/reviews', JSON.stringify(review), {headers: headers})
      .subscribe(res => {
        console.log(res.json());
      });

  }

I read this tutorial there I found this code.please help me out.This is the Service class that is used here in the code.And when can we use Observables and promises?

For references and understandings I have read the stack answers of a post.

Community
  • 1
  • 1
Aditya
  • 2,358
  • 6
  • 35
  • 61

1 Answers1

1

What's done here is someone who prefers Promise over Observable, but it's implemented in a curious way. For instance, using the toPromise operator and the async/await functionality you can get a much more understandable code of the getReviews() like here:

async getReviews(): Promise<any> {
    if (!this.data) {
        this.data = await this.http.get('http://localhost:8080/api/reviews')
            .map(res => res.json())
            .toPromise()

    }
    return this.data;
}

The benefit of this, is that if there are multiple calls on the getReviews() method, before data is returned, the API is only called once. With 'your' implementation, it's very well possible the API is called multiple times, to obtain the same set of data

To answer your questions in your code:

  • The use of Promise.resolve() there is to return the cached data result in promise form. This way the return type of the method is always Promise<any>, so you can always use this.getReviews().then(...). Adding strict return types to methods will make this clear. In my example I've flipped the check, which means it will always return the same promise.
  • The map operator is an Observable (rxjs) operator, used to modify the data before it's send to the subscriber. Not to be confused with the default map operator on an array, which roughly does the same.
  • Headers are used when the requesting server needs them. In this case it's telling the server that the payload of the request consists of JSON data
Poul Kruijt
  • 69,713
  • 12
  • 145
  • 149
  • Thanks for the efforts that you showed on my post :)...I have certain questions 1.)How can we know that the API call is multiple times in my code? 2.)I have not understood the use of async/await and .toPromise functionality.(I am a newbie Pierre using the code)Please clear the doubts.And Last thing is that what is the use of this code `if (this.data) { return Promise.resolve(this.data) }` – Aditya May 10 '17 at 08:05
  • 1
    1. If you have 2 components both calling the `getReviews()` at the same time, two requests will occur in the network tab of your browsers developers tool. 2. `toPromise` is an rxjs operator to transform an observable to a promise. Which means you can use `then()`. Async/await are new typescript operators. Google them for a good explanation. The main thing to know, is that an async method always returns a Promise. 3. I've explained the `Promise.resolve`. This returns a promise which will send `this.data` in the `then(data)` – Poul Kruijt May 10 '17 at 08:25