angelnikolov / ts-cacheable

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

Cache returns empty response unless configured with async #66

Closed michaelz closed 4 years ago

michaelz commented 4 years ago

Hi !

I'm having some trouble understanding something.

I added the @cacheable decorator on a API call with the following parameters:

@Cacheable({
        maxAge: FIND_ALL_PRODUCTS_CACHE_MAX_AGE, // 1 min
        maxCacheCount: 4,
        storageStrategy: DOMStorageStrategy // just to debug
        async: true
    })

It works fine.

Now I don't get why I need the async option. If I remove it, my method doesn't finish and the components think the service is loading data indefinitely.

Is this related to the change implemented in October ?

angelnikolov commented 4 years ago

@michaelz Can you tell me a little more about your set-up? Is this an Angular app? What async does is to add an artificial delay(0) operator to the stream, so it resolves in the next tick. There are frameworks which hook into those types of tasks and detect changes (update).

michaelz commented 4 years ago

Thank you for you reply,

Yes it is an Angular app, and the observables I'm working with are quite complex. In some cases we had to use delay(0) as well, but it has some unwanted side-effects sometimes. We try to avoid them if the problem can be resolved in an other way.

angelnikolov commented 4 years ago

The cached methds return synchronously when there is cache, which doesn't activate Angular's change detection. Can you show me an example call to a cached method?

angelnikolov commented 4 years ago

@michaelz Ping.

michaelz commented 4 years ago

Sorry for the late reply @angelnikolov

I make a simple http call :

@Cacheable({
        maxAge: FIND_ALL_PRODUCTS_CACHE_MAX_AGE,
        maxCacheCount: NUMBER_OF_LEVELS,
        shouldCacheDecider: (response: SearchResult) => !!response &&
            !!response.productIds && response.productIds.length > 0,
        async: true
    })
findAllProducts() {
    //...
    return this.http.get(myUrl).pipe(retry(RETRY));
}
angelnikolov commented 4 years ago

I am not sure what is the issue there, are you using Angular + ChangeDetectionStrategy.OnPush?

michaelz commented 4 years ago

Yes we are using this in the code for performance reasons. So that's maybe why there is an issue...

angelnikolov commented 4 years ago

@michaelz In that case you might need to add markForCheck or detectChanges (in case of Ivy) when data is resolved.