angelnikolov / ts-cacheable

Observable/Promise Cache Decorator
https://npmjs.com/package/ts-cacheable
ISC License
340 stars 42 forks source link

[Question] Can I cache some api call with inner params ? #46

Closed marcio199226 closed 5 years ago

marcio199226 commented 5 years ago

Hi I will explain my question with simple example:

  @Cacheable({
    maxAge: 60000,
    maxCacheCount: 10,
    cacheBusterObserver: entityBustCache$.asObservable()
  })
  list(payload: any = {}): Observable<any> {
    return this._http.post('${environment.baseUrl}/some/api', { ...payload, inner_param: this._someService.getObservable().value });
  }

So my question is how can I cache some endpoints with inner params that are not provided by method call? I have tried to cache internal closure with all params but without success

  list(payload: any = {}): Observable<any> {
    payload = { inner_param: this._someService.getObservable().value, ...payload };

    @Cacheable({
      maxAge: 60000,
      maxCacheCount: 10,
      cacheBusterObserver: entityBustCache$.asObservable()
    })
    const apiCall = (p) => this._http.post('${environment.baseUrl}/some/api', p)

    return apiCall(payload);
  }

Or I have to move all params to method definition in in my case:

list(payload: any = {}, inner_param): Observable<any> {
  // code
}

Best regards and thanks for this awesome library !

P.S I think that decorators can only decorates methods/properties of class, so maybe we could add an additional param to Cacheable decorator something like this:

@Cacheable({
  parameters: {}
})

And merge this option before this line https://github.com/angelnikolov/ngx-cacheable/blob/master/cacheable.decorator.ts#L43? Do you think it could work?

RE P.S

Seems that something like this is working properly:

  list(payload: any = {}): Observable<any> {
    payload = { ...payload, inner_param: this._someService.getObservable().value };
    return this._listEntity(payload);
  }

  @Cacheable({
    maxAge: 60000,
    maxCacheCount: 10,
    cacheBusterObserver: BustCache$.asObservable()
  })
  private _listEntity(payload: any = {}): Observable<any> {
    return this._http.post(`${environment.baseUrl}/some/api`, payload);
  }
angelnikolov commented 5 years ago

Yes, either that, or provide a custom ICacheRequestResolver to the decorator which might have access to the extra parameter you need. But I still think that your idea in the end is better :)

marcio199226 commented 5 years ago

Yeah I think too that that the last one is the best option.

I have another question can I use multiple @CacheBuster on the same method?Or i have to use one only i then bust some other caches in actions where that method was used ?

angelnikolov commented 5 years ago

You can decorate the method with as many decorators as you want, but I would rather suggest that you combine two cache buster subjects into one stream and provide that to your @Cacheable-decorated methods.

marcio199226 commented 5 years ago

Ok I should merge it by merge operator or concat ? The cache shoulds bust as soon as one of them emits new value

marcio199226 commented 5 years ago

Hi @angelnikolov can you show an example how to merge to subject for CacheBuster ?

angelnikolov commented 5 years ago

@marcio199226 cacheBusterObserver: merge(cacheBusterSubject1, cacheBusterSubject2)

marcio199226 commented 5 years ago

Thx I will try it, vs code highlight it as error so i thought that merging is not enough

angelnikolov commented 5 years ago

It must be cacheBusterObserver: merge(cacheBusterSubject1.asObservable(), cacheBusterSubject2.asObservable()), sorry :)