user2759965 user2759965 - 18 days ago 5
TypeScript Question

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);
}

}

Answer

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));
}