2017-07-01 57 views
1

我想弄清楚如何在我的角度類中使用異步/等待。 我有一個PostService從api獲取帖子,但依賴於AreaService,以便PostService知道從哪個區域獲取帖子。不能完全弄清楚如何告訴我的角色類PostService等待來自我的AreaService的數據。 來自AreaService的正確響應將是字符串「有趣」。 PostService然後會在this.areas數組中使用這個有趣的字符串從當前選擇的區域向用戶顯示帖子 當前錯誤是:Uncaught(在promise中):錯誤:錯誤:0:0由以下原因引起:無法讀取屬性未定義在角度2中使用異步/等待功能

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

    } 

從/地區傳入的JSON/

[ 
     { 
      "name": "fun" 
     }, 
     { 
      "name": "information" 
     } 
    ] 

回答

3

,如果你與觀測工作你不需要async/await。您需要使用mergeMap運營商[email protected]flatMap[email protected]

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()); 
    }); 
} 
+0

實現它告訴我之後,一個功能既不是無效或任何必須返回值 –

+0

@CameronGilbert,是的,只需在'this.areaService.getAreas()。mergeMap ...'之前添加'return'即可。我已經更新了答案 –

+1

工作感謝+1 –

2

您可以使用flatMapmergeMap

getPost(): Observable<Post[]> { 
    return this.http.get('http://localhost:8000/areas/', options) 
    .map((res: any) => res.json()) 
    .flatMap((area: any) => { 
     return this.http.get('http://localhost:8000/areas/'+ area[0].name +'/', options) 
     .map((response: Response) => response.json());  
     .map((res: any) => res.json()); 
    }); 
}