I am trying to figure out how to use async/await in my angular classes. I have a PostService that gets posts from an api but is reliant on the AreaService so that PostService knows which area to get the post from. Can't quite figure out how to tell my angular class PostService to wait on data from my AreaService. A correct response from AreaService would be the string "fun". PostService would then use this fun string in the this.areas array to display posts to the user from the currently selected area The current error is: Uncaught (in promise): Error: Error in :0:0 caused by: Cannot read property 'name' of undefined
postservice
import { Injectable, OnDestroy } from '@angular/core';
import { Http, Headers, RequestOptions, Response } from '@angular/http';
import { Observable} from 'rxjs';
import 'rxjs/add/operator/map';
import { AuthenticationService, AreaService, MessageService} from './index';
import { Post, Area} from '../_models/index';
@Injectable()
export class PostService {
areas: Area[] = [];
constructor(
private http: Http,
private authenticationService: AuthenticationService,
private areaService: AreaService,
private messageService: MessageService
) {
}
getPosts(): Observable<Post[]> {
this.areaService.getAreas().subscribe(area => { this.areas = area;});
// add authorization header with jwt token
let headers = new Headers();
headers.append('Authorization','token ' + this.authenticationService.token);
headers.append('Content-Type', 'application/json');
let options = new RequestOptions({
headers: headers
});
// get posts from api
return this.http.get('http://localhost:8000/areas/'+ this.areas[0].name +'/', options)
.map((response: Response) => response.json());
}
}
areaservice
import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptions, Response } from '@angular/http';
import { Observable, Subject } from 'rxjs';
import 'rxjs/add/operator/map';
import { AuthenticationService, MessageService } from './index';
import { Area } from '../_models/index';
@Injectable()
export class AreaService {
public areas: Observable<Area[]> ;
subject:Subject<Area[]> = new Subject();
public currentArea: string = "fun";
constructor(
private http: Http,
private authenticationService: AuthenticationService,
private messageService: MessageService) {
}
getAreas(): Observable<Area[]> {
// add authorization header with jwt token
let headers = new Headers();
headers.append('Authorization','token ' + this.authenticationService.token);
headers.append('Content-Type', 'application/json');
let options = new RequestOptions({
headers: headers
});
// get areas from api
return this.http.get('http://localhost:8000/areas/', options)
.map((response: Response) => response.json());
// this.areas = response.json();
// console.log("h");
// this.messageService.sendMessage(this.areas[0].name);
//this.messageService.sendMessage(this.areas[0].name);
}
}
area.ts
import { Injectable } from '@angular/core';
@Injectable()
export class Area{
name:string;
currentArea:number = 1;
constructor(name:string) {
this.name = name;
}
public static createEmptyrea():Area{
return new Area("");
}
setArea(val:number) {
this.currentArea = val;
}
}
incoming json from /areas/
[
{
"name": "fun"
},
{
"name": "information"
}
]
You don't need async/await if you're working with observables. You need to use mergeMap operator for rxjs@5 or flatMap for rxjs@4:
getPosts(): Observable<Post[]> {
// subscribe until the area is available
return this.areaService.getAreas().mergeMap(area => {
// add authorization header with jwt token
let headers = new Headers();
headers.append('Authorization', 'token ' + this.authenticationService.token);
headers.append('Content-Type', 'application/json');
let options = new RequestOptions({
headers: headers
});
// use the area to get the response
return this.http.get('http://localhost:8000/areas/' + area.name + '/', options)
.map((response: Response) => response.json());
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With