Andy Band
Andy Band

Reputation: 313

correct using Promise.all for more http request

I would like to have two HTTP request for obtain first the list of Items(in Json) and the second request the Item that user have selected. But when I try to run the code, the console displays the following error:

response getItems {with the JSON array}

response getTipology undefined

Promise getItems & getTipology:{2 array, the first is correct and the second is undefined}

I'm new to Angular but could some one please help me with this. Thanks

item: any;
    onItemChanged: BehaviorSubject<any>;
    items: any[];
    onItemsChanged: BehaviorSubject<any>;

    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any
        {
            this.routeParams = route.params;

            return new Promise((resolve, reject) => {

                Promise.all([
                    this.getItems(),
                    this.getTipology()
                ]).then((result) => { // Success
                        console.log('Promise getItems & getTipology:', result);
                        resolve();
                    },
                    msg => { // Error
                        reject(msg);
                    }
                );
            });
        }


getTipology(): Promise<any>
    {
        return new Promise((resolve, reject) => {
            this._httpClient.get('https://www.andreabandiera.it/get_tipology_by_id.php?ID=' + this.routeParams.id)
                .subscribe((response: any) => {
                    this.item = response[1];
                    this.onItemChanged.next(this.item);
                    resolve(response[1]);
                    console.log('response getTipology', this.item);
                }, reject);
        });
    }



getItems(): Promise<any>
    {
        return new Promise((resolve, reject) => {
            this._httpClient.get('https://www.andreabandiera.it/get_tipology.php')
                .subscribe((response: any) => {
                    this.items = response[0];
                    this.onItemsChanged.next(this.items);
                    resolve(response[0]);
                    console.log('response getItems', this.items);
                }, reject);
        });
    }

Upvotes: 2

Views: 1733

Answers (2)

rafaelwalter
rafaelwalter

Reputation: 136

It's not wrong how you are doing things, but i would strongly suggest using observables to do this. Angular's httpclient works 100% on observables and is pretty straight forward once you get it.

With observables its possible to concatenate, merge, switch and a lot of other operations that can be found out in rxjs docs.

I would suggest some refactoring on your code:

  1. Change getTipology and getItems methods so they return the actual this._httpClient.get function call, without its subscription.
getTipology() {
  return this._httpClient.get('https://www.andreabandiera.it/get_tipology_by_id.php?ID=' + this.routeParams.id);
}
  1. Subscribe to both at the same place (forward explication) and manage data at the subscription or take a look into observable pipes, which its possible to handle data accordingly per function.
  2. It isnt clear to me if what you are looking for is a parallel or a operation where the second request depends on the response of the first one (waterfall). For a parallel request i would suggest taking a look into rxjs.forkJoin or for the waterfall condition perhaps rxjs.switchMap can do the trick.

Let me know if this workout for you.

Upvotes: 0

Noremac
Noremac

Reputation: 594

promises are essentially obsolete and observables should be used in their place because they are more modern and flexible. First off don't wrap an observable within a promise. Call toPromise() on the observable to convert it to a promise. I really recommend you try using observables instead of promises like so:

forkJoin(
    this._httpClient.get('https://www.andreabandiera.it/get_tipology.php'),
    this._httpClient.get('https://www.andreabandiera.it/get_tipology_by_id.php?ID=' + this.routeParams.id)
).subscribe((results) => {
    // access tipology via results[0] and the item via results[1]
}); 

Upvotes: 3

Related Questions