0

i'm using a cache service where i will store the api data in the file like this

import { Inject, Injectable } from "@angular/core";
import { Observable, firstValueFrom } from "rxjs";

@Injectable({
    providedIn: 'root'
})
export class ApiCacheService{
    api_data: any = null;

    constructor(
        private _api_service:ApiService
    ) { }
    
    public clearApiCache() {
        this.api_data=null
    }

    public async getApiData(body: any) {
        if (!this.api_data) {
            await firstValueFrom(this._api_service.getData(body)).then(res => {
                this.api_data=res
            }, err => {
                throw new Error("Error in api"+err["message"])
            })
         }
        return this.api_data
    }

}

my first component call will be

export class TestApiComponent {

    constructor(
        private _api_cache_service: ApiCacheService
    ) { }

    ngOnInit() {
        this.getData()
     }
    
    /**
     * function will get the data from the cache service
     */
    private async getData() {
        try {
            let body = {
                id:"1001"
            }
            let data = await this._api_cache_service.getApiData(body)
            // .... some other logic
        }catch{}
    }

}

and my second component also will call the same function parallel to the first one like this

export class SetApiComponent {

    constructor(
        private _api_cache_service: ApiCacheService
    ) { }

    ngOnInit() {
        this.setFunctionData()
     }
    
    /**
     * function will get the data from the cache service
     */
    private async setFunctionData() {
        try {
            let body = {
                id:"1001"
            }
            let data = await this._api_cache_service.getApiData(body)
            // .... some other logic
        }catch{}
    }

}

now when calling to the cache there is no data in the service and it will send request to the api, then before api response second service initiated the call and there is no data then it will also make a api call (for angular 13 and above).

here i need to make only one api call for multiple service calls and need to return same data to all services once the call was completed (need to call another api for different body in the request body).

saiteja
  • 13
  • 3

1 Answers1

0

The most simple solution, I think, would be that you set a property in the cache service that indicates if the getApiData method is running or not. In case it is not, it fetches the data through the API and it it is, then it uses an interval to check if the response has arrived or not:



export class ApiCacheService {
  public api_data: any = null;

  private getApiDataRunning: boolean = false;

  constructor(
    private _api_service: ApiService,
  ) { }

  public clearApiCache() {
    this.api_data = null
  }

  public async getApiData(body: any) {
    if (this.api_data) {
      return this.api_data;

    } else if (this.getApiDataRunning) {
      await this.awaitApiData().then(api_data => {
        this.api_data = api_data;
      }, err => {
        throw new Error("Error in api"+err["message"]);
      });
      
      return this.api_data

    } else {
      this.getApiDataRunning = true;

      await this.fetchApiData().then(api_data => {
        this.api_data = api_data;
      }, err => {
        throw new Error("Error in api"+err["message"]);
      });

      this.getApiDataRunning = false;
      return this.api_data
    }
  }

  private async awaitApiData() {
    return await new Promise(resolve => {
      const interval = setInterval(() => {
        if (this.api_data) {
          resolve(this.api_data);
          clearInterval(interval);
        };
      }, 2000);
    });
  }

  private async fetchApiData() {
    return await firstValueFrom(this._api_service.getData(body)).then(res => {
      resolve(res);
    }, error => {
      reject(error);
    });
  }
}
Leonardum
  • 444
  • 4
  • 8
  • hi thank you for your answer, but if i added a flag value then when the second request is initialted then the flag value will be true and i will get null data as result of failed if condition. i need to await for the request completion and same data need to transfer to the 2 service calls – saiteja May 29 '23 at 05:27
  • Hey, what you say makes sense. I have updated my answer. This implementation uses an interval to wait for the first call to set the value of the api_data. Would this work? – Leonardum May 30 '23 at 09:39
  • 1
    hi, sorry for late replay your answer worked perfectly, as for fast response i reduced my setInterval duration, thank you. – saiteja Jun 02 '23 at 04:14