locnguyen
locnguyen

Reputation: 841

angular 2 promise to observable

Following along the Angular 2 tutorial. I am trying to convert the following methods from promises to observables. My attempt is below.

1) Are the conversions corret?

2) How would I convert the getGroup() method

getGroups()

  // Promise
  getGroups(): Promise<Group[]> {
    return this.http.get(this.groupsUrl)
      .toPromise()
      .then(response => response.json().data as Group[])
      .catch(this.handleError);
  }
  // Observable
  getGroups(): Observable<Group[]> {
    return this.http.get(this.groupsUrl)
      .map(this.extractData)
      .catch(this.handleError);
  }
  private extractData(response: Response) {
    let body = response.json();
    return body.data || { };
  }

getGroup()

  // Promise
  getGroup(id: number): Promise<Group> {
    return this.getGroups()
      .then(groups => groups.find(group => group.id === id));
  }
  // Observable
  // ================
  // HOW?
  // ================

createGroup()

  // Promise
  createGroup(name: string): Promise<Group> {
    return this.http
      .post(this.groupsUrl, JSON.stringify({name: name}), {headers: this.headers})
      .toPromise()
      .then(res => res.json().data)
      .catch(this.handleError);
  }
  // Observable
  createGroup(name: string): Observable<Group> {
    return this.http
      .post(this.groupsUrl, JSON.stringify({name: name}), {headers: this.headers})
      .map(res => res.json().data)
      .catch(this.handleError);
  }

updateGroup()

  // Promise
  updateGroup(group: Group): Promise<Group> {
    const url = `${this.groupsUrl}/${group.id}`;
    return this.http
      .put(url, JSON.stringify(group), {headers: this.headers})
      .toPromise()
      .then(() => group)
      .catch(this.handleError);
  }
  // Observable
  updateGroup(group: Group): Observable<Group> {
    const url = `${this.groupsUrl}/${group.id}`;
    return this.http
      .put(url, JSON.stringify(group), {headers: this.headers})
      .map(() => group)
      .catch(this.handleError);
  }

deleteGroup()

  // Promise
  deleteGroup(id: number): Promise<void> {
    const url = `${this.groupsUrl}/${id}`;
    return this.http
      .delete(url, {headers: this.headers})
      .toPromise()
      .then(() => null)
      .catch(this.handleError);
  }
  // Observable
  deleteGroup(id: number): Observable<void> {
    const url = `${this.groupsUrl}/${id}`;
    return this.http
      .delete(url, {headers: this.headers})
      .map(() => null)
      .catch(this.handleError);
  }

}

Upvotes: 0

Views: 2662

Answers (1)

Pankaj Parkar
Pankaj Parkar

Reputation: 136134

1) Are the conversions correct?

Conversion isn't seems to be correct. By passing function references to the observable callbacks you are going to lose this context. You have to use Arrow function to keep touch in with this & call function explicitly.

// Observable
getGroups(): Observable<Group[]> {
    return this.http.get(this.groupsUrl)
      .map(this.extractData) //don't pass function reference
      .catch(this.handleError);
}

should be

// Observable
getGroups(): Observable<Group[]> {
  return this.http.get(this.groupsUrl)
    //.map(this.extractData.bind()) //this would work but its bad pattern
    .map(()=> this.extractData())
    .catch(this.handleError);
}

Follow the same thing for other functions if you did same thing over somewhere in your code.

2) How would I convert the getGroup() method

It will simply look like below

getGroup(id: number): Promise<Group> {
    return this.getGroups()
      .map(groups => groups.find(group => group.id === id));
}

Upvotes: 1

Related Questions