Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using async/await function in angular 2

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"
        }
    ]
like image 220
Cameron Gilbert Avatar asked Apr 30 '26 11:04

Cameron Gilbert


1 Answers

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());
    });
}
like image 197
Max Koretskyi Avatar answered May 03 '26 01:05

Max Koretskyi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!