Leandro Castro
Leandro Castro

Reputation: 251

How to do a method run before each service call?(Angular 7)

I'm trying get a "payload" from localstorage before than execute services method. Actualy i'm trying to do it on constructor method, but sometimes the variable "this.payload" isn't setted when a call a method.

This is my code

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import * as Globals from '../../globals';
import { Observable, of } from 'rxjs';
import { LocalStorage } from '@ngx-pwa/local-storage';

@Injectable({
    providedIn: 'root'
})
export class RechargesService {

    public payload;

    constructor(
        private http: HttpClient,
        public localStorage: LocalStorage
    ) {
        this.localStorage.getItem("payload").subscribe((payload) => {
            this.payload = payload;
        })
    }


    list(): Observable<any> {
        return this.http.post(Globals.url_api + "recharges/list", {
            // Sometimes this.payload isn't setted, i don't know why
            "payload": this.payload
        });
    }
}

What's the correct way to do it? I know that in controller, i shouldn't write anything on constructor method, but in service it's correct?

Upvotes: 1

Views: 1281

Answers (3)

Harun Yilmaz
Harun Yilmaz

Reputation: 8558

If you want to get payload before every list() call, you can do it like following:

First create a method returns an observable that gets value from local storage, then use switchMap to return an inner observable (which is HTTP get request)

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import * as Globals from '../../globals';
import { Observable, of} from 'rxjs';
import { tap, switchMap } from 'rxjs/operators';
import { LocalStorage } from '@ngx-pwa/local-storage';

@Injectable({
    providedIn: 'root'
})

export class RechargesService {

public payload;

    constructor(
        private http: HttpClient,
        public localStorage: LocalStorage
    ) {

    }

     getPayload = () => {

        return this.localStorage.getItem("payload").pipe(tap(payload => this.payload = payload)); // <--- the tap() may be redundant here. you can simply get payload in list() method

     }


    list(): Observable<any> {

        return this.getPayload().pipe(
            switchMap(payload => {
               return this.http.post(Globals.url_api + "recharges/list", {"payload": this.payload})  // <--- You can use payload instead of this.payload since localStorage already returns payload
            })
        );
    }

}

switchMap: https://www.learnrxjs.io/operators/transformation/switchmap.html

do/tap: https://www.learnrxjs.io/operators/utility/do.html

Upvotes: 2

Rahul Sharma
Rahul Sharma

Reputation: 10111

create a getPayload function tp get local-storage data and use switchMap in list function to pass getPayaload data to api.

getPayload(){
    return this.localStorage.getItem("payload");
}

list(payload): Observable<any> {
    return getPayload().pipe(
        switchMap(
            (payload) => {
                return this.http.post(Globals.url_api + "recharges/list", {
                    payload
                })
            },
        )
    );
}

Upvotes: 1

Rafael Lucini
Rafael Lucini

Reputation: 599

Use forkJoin Operator

https://www.learnrxjs.io/operators/combination/forkjoin.html

forkJoin(
      this._myService.makeRequest('Request One', 2000),
      this._myService.makeRequest('Request Two', 1000),
      this._myService.makeRequest('Request Three', 3000)
    )
    .subscribe(([res1, res2, res3]) => {
      this.propOne = res1;
      this.propTwo = res2;
      this.propThree = res3;
    });

Upvotes: 0

Related Questions