Búsqueda de sitios web

typescript - Usando función async/await en angular 2


Estoy intentando averiguar cómo usar async/await en mis clases de Angular. Tengo un PostService que obtiene publicaciones de una API, pero depende del AreaService para que PostService sepa de qué área obtener la publicación. No consigo entender cómo decirle a mi clase de Angular PostService que espere los datos de mi AreaService. Una respuesta correcta de AreaService sería la cadena "fun". PostService usaría entonces esta cadena "fun" en el array this.areas para mostrar publicaciones al usuario desde el área seleccionada actualmente. El error actual es: Uncaught (in promise): Error: Error en :0:0 causado por: Cannot read property 'name' of undefined

postservicio

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

        }
      }

servicio de área

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

área.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 entrante desde /areas/

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

Respuesta #1

No necesitas async/await si estás trabajando con observables. Necesitas usar el operador mergeMap para rxjs@5 o flatMap para 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());
    });
}

Respuesta #2

Puedes usar flatMap o mergeMap:

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

Artículos relacionados