Coder Social home page Coder Social logo

ts-cacheable's People

Contributors

angelnikolov avatar cognitivedesire avatar dependabot[bot] avatar ebrehault avatar hacklone avatar juan-db avatar pcbowers avatar ragtam avatar serrulien avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ts-cacheable's Issues

turn off globally

I'm doing server rendering and I'm trying to figure out the best way to turn this off when its run on the server.

Or basically turn it on / off based on some global setting.

Module build failing (v1.1.9)

I just upgraded version of 1.1.9 of ngx-cacheable and when I try and compile my app I get the following error:

Module build failed (from ./node_modules/@ngtools/webpack/src/index.js):
Error: C:\Users\Emily Cheyne\source\repos\EmilyEMRVS\EmilyEMRVS\ClientApp\node_modules\ngx-cacheable\index.ts is missing from the TypeScript compilation. Please make sure it is in your tsconfig via the 'files' or 'include' property.
The missing file seems to be part of a third party library. TS files in published libraries are often a sign of a badly packaged library. Please open an issue in the library repository to alert its author and ask them to package the library using the Angular Package Format (https://goo.gl/jB3GVv).
    at AngularCompilerPlugin.getCompiledFile (C:\Users\Emily Cheyne\source\repos\EmilyEMRVS\EmilyEMRVS\ClientApp\node_modules\@ngtools\webpack\src\angular_compiler_plugin.js:752:23)
    at plugin.done.then (C:\Users\Emily Cheyne\source\repos\EmilyEMRVS\EmilyEMRVS\ClientApp\node_modules\@ngtools\webpack\src\loader.js:41:31)
    at process._tickCallback (internal/process/next_tick.js:68:7)```

Don't cache if response is empty

Hi!
First of: I freaking love this package, thank you for sharing it!!!

And now to the issue:
I currently have an issue where if the response is empty (no errors, just an empty response), the data is still cached.

It is highly unlikely that the API is returning an empty response, but it can happen.

I am already doing checks on empty data, wrong data, etc.

I would like to avoid busting the cache if the response is empty.
Is there a clever way to ensure that the response is not saved if it is empty?
And maybe the possibility of adding this as a configuration in the future?

Doesn't Cancel Observable using async

See example Below.

Expected results:
When using the Async pipe and navigating to a new route, any pending requests should be canceled.

Actual Results:
Pending requests stay open until completed. This causes issues in performance, since when you navigate to a new route the old request(s) is taking up request threads.

In the example below, you can see when you navigate from route1 to route2 the request is canceled when not using the decorator. Adding the decorator to the request keeps the request open even after navigating away. I understand that you may want to go back to that request later, but if it doesn't complete i dont think it should be kept.

This same thing happens when you make a different request to a cached function, the original request is still pending and is not canceled, even if you only have the default one request set to cache. I would only expect that it would keep the previous request if the max cache count is set to more than one. this becomes a large performance issue when you have an app that makes multiple new requests after some parameter changes, all the old request are still pending and are processed, then the new request are sent off.

Example

LICENSE file

Hi.

I see the repository does not have a license file. According to the npm page for the project it is licensed under the ISC license.

I'd recommend adding a LICENSE file to the repository itself.

You can copy the license from here and just populate the year and fullname fields.

Serialized parameters are used to call the original method on cache miss

Hi there,

first, thanks for this very useful library!

I noticed a problem with non-primitive parameters in methods annotaged with @Cacheable.

Cacheable uses serialized values instead of the original values when calling a method in case of a cache miss. This will cause problems, if the method needs to access methods or properties of the original parameter values.

The attached diff fixes the problem in cacheable.decorator.js in my case:
cacheable.decorator.js.diff.txt

Best regards
Ingo

Latest release for rxjs 5.x ?

Hi, this is a very good library I'd like to use but I'm stuck with the version 5.x of rxjs. I tried to use the 1.0.1 version of ngx-cacheable but the cacheBusterObserver doesn't seem to work.

Could you release the latest version with compatibility with rxjs 5?

Thanks!

how to bust a cache?

Great module! I'm confused how to bust the cache based on an action or another API call (such as "add item, remove item, etc.)

a sample would help.

Thanks

change default cache resolver

the default cache resolver simply does a JSON.stringify test against the old and new parameters. This does not take into account the position of the properties and can lead to false results (depending on your point of view).

If you were to use object-hash to compare the two objects this is no longer an issue. See the code sample below

const hash = require('object-hash');

const p1 = { d1: 'd1', d2: 'd2' };
const p2 = { d2: 'd2', d1: 'd1' };

const hash1 = hash(p1);
const hash2 = hash(p2);

console.log('json', JSON.stringify(p1) === JSON.stringify(p2));
console.log('hash', hash1, hash2, hash1 === hash2);

the result of this is

json false
hash f4c434a0e4c11deb776f4281c9b3848ccbe63578 f4c434a0e4c11deb776f4281c9b3848ccbe63578 true

this could be implemented by default , or by adding an option to specify a different cache resolver so that it won't break existing code that relies on key position creating different cache results

CacheBuster not working

Hi,

I tried to implement Cacheable and CacheBuster. Cacheable is working fine but somehow CacheBuster is not working. Below is the code:

`
import { Cacheable, CacheBuster } from 'ngx-cacheable';
const countryCacheBuster$ = new Subject();

@cachebuster({
cacheBusterNotifier: countryCacheBuster$
})
public createCountry(country: Country): Observable {
return this.http
.post(${this.url}/api/createCountry, country, {
withCredentials: true
});
}

@Cacheable({
cacheBusterObserver: countryCacheBuster$
})
getCountrys(): Observable {
return this.http.get(${this.url}/api/getCountryList)
.pipe(
catchError(error => error)
);
}
`

Where I am doing wrong ? Please help.

How to cache GET/POST etc for multible critera

I would like to cache the following example:

/service/key?=1
/service/key?=2

Etc. Additional requests to the above keys would returned from cache. Keys not matching would be returned from the HTTPClient with the results being added to the cache.

The data requests could be from either Get or Post.

Thank you for your guidance.

cacheBusterObserver with maxCacheCount

when you bust the cache, you bust it for all.

merge(
        globalCacheBusterNotifier.asObservable(),
        cacheConfig.cacheBusterObserver
          ? cacheConfig.cacheBusterObserver
          : empty()
      ).subscribe(_ => {
        storageStrategy.removeAll(cacheKey);
        pendingCachePairs.length = 0;
      });

for maxCacheCount you remove one:

if (
                  !cacheConfig.maxCacheCount ||
                  cacheConfig.maxCacheCount === 1 ||
                  (cacheConfig.maxCacheCount &&
                    cacheConfig.maxCacheCount < cachePairs.length + 1)
                ) {
                  storageStrategy.removeAtIndex(0, cacheKey);
                }

Would be nice if cacheBuster had an option to provide the parameters - that way you could remove only some values :)

Change maxCacheCount default?

Hi,
Thanks for making the effort to provide a caching library. It looks very promising!

Some feedback

I especially like the ability to evict the cache, but as #56 points out its not currently very useful for maxCacheCount. Also, "cacheBusting" is known as cacheEviction, and is a well-known term. Along the same lines, I don't think it makes sense to limit cache size based on the number of combinations of paramaters for a method. Perhaps it would be better to separate the Cache storage config and the cache strategy?

I find the default behaviour a little bit odd compared to other caching libraries I have used eg eh-cache et.c Typically, a single Cacheable decorator will key up all parameters and maintain a cache for each combination, as compared to the default behavior for ngx-cachable of killing the cache when calling with a new parameter. Please consider changing default behavior for Cacheable. I find it counter-intuitive compared to other libraries/standards, and there are already a few issues that has arisen from this, like #26 and #42

Rather than specifying a maxCacheCount of Number.POSITIVE_INFINITY and a TTL on all the cache-decorators, it would be useful to override the defaults globally. Is that possible?

problem with extended methods

I have a base class which implements find, using as a generic and a unique url for each model, so a GET to /api/model1/find and /api/model2/find for example

each model data service extends this base service

however, if I @Cacheable() the find method in the base class, then the same data is returned from in-memory cache for any model.

ie if I first get users , then a subsequent call to find in the customer model also returns the list of users

The only way I see round this is to override each method in each model, and add a cache at that level but it seems a seriously nasty hack

'Cacheable' is not initialized at ngx-cacheable\dist\cacheable.decorator.ts

Hello!

First I want to thank you for the great work!

I am having the following error in the latest versions (1.1.0, 1.1.1, 1.1.2, 1.1.3) when running ng serve:

Only initialized variables and constants can be referenced in decorators because the value of this variable is needed by the template compiler in 'Cacheable'
'Cacheable' references 'Cacheable'
'Cacheable' is not initialized at ngx-cacheable\dist\cacheable.decorator.ts(4,22).

If I change to version 1.0.9, it works normally.

I'm using node 11.12.0 and Angular CLI 7.3.6.

Thank you for you attention.

image

image

Anguar 7 - Request URL is changed when using @Cacheable

Hello,

I found this library from an article here

I added the @Cacheable annotation to a request method that makes a GET request to an API.

  @Cacheable({ cacheBusterObserver: cacheBuster$ })
  makeRequest<T>(requestType: string, apiCall: string, params: HttpParams): Observable<T> {
    return this.http.request<T>(requestType, apiCall, {responseType: 'json', params})
      .pipe(catchError(HttpRequestService.errorHandler));
  }

The base URL looks like this when no @Cacheable is used :

https://<server_name>:8443/api/users.

The HttpParams have a page and size parameters. The whole URL looks like :

https://<server_name>:8443/api/users?page=1&size=10

However when adding @Cacheable the request URL looks like this (web console) :

https://<server_name>:8443/api/users?updates=%5Bobject%20Object%5D&updates=%5Bobject%20Object%5D&cloneFrom=%5Bobject%20Object%5D&encoder=%5Bobject%20Object%5D&map=null

I then get no results back as the server returns a 400 error. Since that end point does not exist.

This is what my whole service looks like.

const cacheBuster$ = new Subject<void>();

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

  constructor(private http: HttpClient) { }

  static errorHandler(error: HttpErrorResponse) {
    if (error.error instanceof ErrorEvent) {
      console.error('An error occurred:', error.error.message);
    } else {
      console.error(`Backend returned code ${error.status}, ` + `body was: ${error.error}`);
    }
    return throwError('Something bad happened; please try again later.');
  }

  @Cacheable({ cacheBusterObserver: cacheBuster$ })
  makeRequest<T>(requestType: string, apiCall: string, params: HttpParams): Observable<T> {
    return this.http.request<T>(requestType, apiCall, {responseType: 'json', params})
      .pipe(catchError(HttpRequestService.errorHandler));
  }
}

I am using angular 7 and the new HTTP Client.
Thank you.

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

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);
  }

Services inheriting from common base need different caches.

I really like Cacheable. And I really want it to work for my needs! However, it's currently not working. Here's my scenario:

I have a base service called Repository. All services inherit from it. When I fetch data from each child service, they share the same cache & the service that calls 2nd, gets the first service's data.

The calls in the follow code block are nested for force an order for this example. Typically, there's a race condition and whoever resolves first wins. The response in the 2nd call should be Widget[], however, it comes back as Part[] because of the cache.

this.partsService.find().subscribe((parts) => {
  this.parts = parts;

  this.widgetsService.find().subscribe((widgets) => {
    this.widgets = widgets;
  });
});

widgets.service.ts

import { RepositoryService } from './repository.service';
import { Widget } from '../models';

export class WidgetService extends RepositoryService<Widget> {}

parts.service.ts

import { RepositoryService } from './repository.service';
import { Part } from '../models';

export class PartService extends RepositoryService<Part> {}

repository.service.ts

import { HttpClient, HttpParams } from '@angular/common/http';
import { Observable, Subject } from 'rxjs';
import { Cacheable, CacheBuster } from 'ngx-cacheable';
import { Resource } from '../models/resource.model';
import * as i from 'inflection';

const cacheBuster$ = new Subject<void>();

export class RepositoryService<T extends Resource> {
  private base:string = '/api';
  private collection:string;

  constructor(private http: HttpClient) {
    this.collection = i.underscore(i.pluralize(
      this.constructor.name.replace('Service', '')
    ));
  }

  @Cacheable({
    cacheBusterObserver: cacheBuster$
  })
  public find(query: object = {}): Observable<T[]> {
    const options = { params: new HttpParams() };

    for (const [key, value] of Object.entries(query)) {
      options.params.set(key, value);
    }

    return this.http.get<T[]>(this.url(), options);
  }

  @Cacheable({
    cacheBusterObserver: cacheBuster$
  })
  public findById(id: string): Observable<T> {
    return this.http.get<T>(this.url(id));
  }

  @CacheBuster({
    cacheBusterNotifier: cacheBuster$
  })
  public save(item: T): Observable<T> {
    return item.id ? this.update(item) : this.create(item);
  }

  private create(item: T): Observable<T> {
    return this.http.post<T>(this.url(), item);
  }

  private update(item: T): Observable<T> {
    const { id, ...payload } = <T>item;
    return this.http.patch<T>(this.url(id), payload);
  }

  private url(id?: string) {
    return [this.base, this.collection, id].filter(x => !!x).join('/');
  }
}

Possible to cache multiple invocations of a method, varied by method's arguments?

I've been testing this decorator in an application and was curious if what I'm seeing is the intended behavior or if it's something about my environment.

I've added the @PCacheable() decorator to some API methods that return a Promise.

These methods typically have some parameters to control which object(s) to retrieve from the API (like an object's id, or some filters for a list of objects). An example:

class ApiService {
  @PCacheable()
  public async getObject (id: number): Promise<any> {
    // HTTP call here
  }
}

When this method is called with an id, let's say 1, I see that any future requests with that same id are cached, so the network isn't hit, unless the method is called with a different id, in which case that response is cached. This initially seemed to be working the way I expected, but if I then call the method with id 1 (after it has been called with a different id), the response isn't cached and the network is hit.

Unless I'm mistaken, it appears that only one response for a given method is ever cached at a time, and that cache is cleared if the parameters change, so only subsequent calls with the same id will hit the cache, if any calls with a different id happen after the cache is stored, the cache is cleared entirely for that method.

Is this expected? Looking in the code a bit, it seems that the cacheKey is based on the name of the class and then the name of the method (unless provided in config) separated by a #. And the parameters are only used to determine if the cached value should be used or not (via the result of the cacheResolver).

Is there a way to store a cached response for every variation of the parameters of the method?

I was thinking that the cacheKey could be modified to do this, but we'd need a dynamic way to set that based on the method's parameters, which doesn't seem possible unless I'm missing something.

I tried using the custom cacheHasher but that still didn't seem to allow me to cache multiple calls to the same method, unless I'm doing something wrong.

I've put a stackblitz together that shows what I mean: https://angular-njkvn4.stackblitz.io/ (source: https://stackblitz.com/edit/angular-njkvn4) If you repeatedly press the "Get 1" button, you'll only see one console.log statement, and just one HTTP request, however, if you press "Get 1", "Get 2" and then "Get 1", you'll see it make the request for the 1 post twice because the call with id 2 clears the cache and stores the result of "Get 2" (which is then cleared when "Get 1" is called again).

Thanks!

In some url pattern it is not working

api url: products/3?page=1

3: categoryid

in above api url cache response getting empty but normally api call i get response

Api response:
apiresponse

cached response:
cachedresponse

How to use ngx-cacheable in server side pagination

I am building a app in which i am doing server side pagination by calling a same REST API with different query string on page change event. can i use this library to cache the response of previous pages so that if i go back to previous page , no API call made.

Invalidate cache when parameter is an object

Hi,

I would like to run this test in cacheable.decorator.spec.ts

[...]
  @Cacheable()
  getDataWithParamObj(parameter: any) {
    return this.mockServiceCall(parameter);
  }
[...]
  it("return the cached observable with params object", () => {
    let params = {
      limit: 5,
      stars: ["1"],
      page: 1,
      q: ""
    };
    /**
     * call the service endpoint five hundred times with the same parameter
     * but the service should only be called once, since the observable will be cached
     */
    for (let i = 0; i < 500; i++) {
      service.getDataWithParamObj(params);
    }

    expect(mockServiceCallSpy).toHaveBeenCalledTimes(1);
    /**
     * return the response
     */
    jasmine.clock().tick(1000);

    params.stars.push("2");
    /**
     * call again..
     */
    service.getDataWithParamObj(params);
    /**
     * service call count should still be 1, since we are returning from cache now
     */
    expect(mockServiceCallSpy).toHaveBeenCalledTimes(2);
  });
[...]

Wouldn't it miss a clone of the parameters before saving them as old parameters. or something like that ?

Thank you for your help ๐Ÿ™‚

UPDATE :

If you add cloneDeep of the parameters before the call to the "cacheable observable" it corrects the problem. But I still think it's up to the lib to do the job ๐Ÿ™‚

If I find what I need to modify in the library, I will propose a PR ๐Ÿ˜‰

reload data when cacheBusterNotifier is called

When I save some data Id like that my informations get updated automatically.
Im doing the following:

get(pessoaId): Observable<Array<VideoModel>> {
        return merge(of([]), cacheBuster$).pipe(
            switchMap(() => {
                return this.http.get(`${this.baseUrl}/${pessoaId}`);
            })
        );
    }

 @CacheBuster({
        cacheBusterNotifier: cacheBuster$
    })
    add(video: VideoModel): Observable<VideoModel> {}

But im not sure if this is the best way to accomplish this.
Do you have any idea?

importing DomStorageStrategy

I can't seem to import DomStorageStrategy, perhaps it's not exported?


import { Cacheable } from 'ngx-cacheable';
import { DOMStorageStrategy } from '@ngx-cacheable/common/DOMStorageStrategy';


@Injectable({
  providedIn: 'root'
})
export class UserService {
  private user$: Observable<UserDetailsViewModel> = null;

  constructor(
    private userDetailService: UserDetailService,
    private showErrorService: ShowErrorService,
  ) {}

  @Cacheable({
    maxAge: 1000 * 60 * 60 * 24,
    storageStrategy: DOMStorageStrategy,
  })
  public getAvatar(): Observable<string> {
    return this.userDetailService.UserDetailGetUserAvatar();
  }

I get an error:


Failed to compile.

./src/app/some-services/user.service.ts
Module not found: Error: Can't resolve '@ngx-cacheable/common/DOMStorageStrategy' in '/Users/robertking/go/src/bitbucket.org/borndigital-nz/barker.mybarker/front-end/src/app/some-services'

common.js 404

After upgrading from 1.0.9 to the following, the application gives an error message. I'm using systemjs.config.js in my project to configure reference.

common.js 404.

Please help me.

Ability to pass a custom JSON.stringify replacer

Hi there,

I'm currently having an issue because of a circular structure in an object from another library (which should be cached).
This is easy to fix I could pass a stringify replacer, because I could then ignore the recursive property.

I couldn't find documentation on how to do this currently and I also didn't see an existing issue on this, so I made a new one.

Any help would be appreciated.
Thanks!

changing contents of cached observable

is it possible to change / emit new values from a cached call ?

Let's say I've loaded 40 items from an http call - and these are being displayed onscreen. Another session adds a new item - which notifies via websockets all interested clients.

How can I take this new item and insert it into the cache so my screen is updated withe the new record, without having to re-read the data from the http call ?

TypeError: rxjs_1.of is not a function

followings are the version details

   "ngx-cacheable": "^1.0.6",
   "@angular/common": "^4.0.0",
    "@angular/compiler": "^4.0.0",
    "@angular/core": "^4.3.4",
    "@angular/forms": "^4.0.0",
    "@angular/http": "^4.0.0",
    "rxjs": "^5.1.0",

I have added @Cacheable decorator in user.service.ts file as below

import { Cacheable } from 'ngx-cacheable';
...

@Cacheable()
    getUserDetail(): Observable<any> {
        return this.httpClient
            .get<UserResponse>(`/user/profile`, { withCredentials: true })
            .map((res) => res.item);
    }

bit it throw errors

ERROR TypeError: rxjs_1.of is not a function
at UserService.propertyDescriptor.value [as getUserDetail] (cacheable.decorator.js:60)
at ProfileComponent.getUserDetail (profile.component.ts:73)
at ProfileComponent.ngAfterViewInit (profile.component.ts:60)
at callProviderLifecycles (core.es5.js:11176)
at callElementProvidersLifecycles (core.es5.js:11147)
at callLifecycleHooksChildrenFirst (core.es5.js:11131)
at checkAndUpdateView (core.es5.js:12259)
at callViewAction (core.es5.js:12599)
at execEmbeddedViewsAction (core.es5.js:12557)
at checkAndUpdateView (core.es5.js:12252)

What is the reason and how to solve it?

How do I bust all caches

I really like this library. The one potential deal-breaker for me is that there doesn't seem to be any way to bust all caches (like on logout.)

Am I missing this this functionality?

How to override default values from custom config settings?

Hi,

This is not an issue but more of a query since I'd like to pass some values to the Cacheable decorator dynamically. These would be defined in a config file and converted into an object. Essentially I have a service which contains several methods I'd like to cache like this:
... @Cacheable({ maxAge: this.config.cacheExpirationTimeInMilliseconds }) getCountries() { return this.http.get("api/Countries"); } ...
I'm struggling to do that, since I always get an undefined reference on the config object. What should be the proper way to do this? Or better yet, how can I override default values being used by the decorator and what are those values?

Thanks in advance.

Cache separate by different parameter values

Is it possible to keep caches for old function parameters too?

@Cacheable()
getArticle(id: string): Observable<Article> {
  ....
}

I call this method several times with different articleIds in a view, then none of my requests are being cached actually. My expected behaviour was to cached every article request separately.

Cache returns empty response unless configured with async

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 ?

Ionic 4: still hitting API

Hi, I'm using the Cacheable decorator in one of my service but I always hit the real API.

I'm using Ionic 4 and angular 7.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Cacheable } from 'ngx-cacheable';
import { pipe } from 'rxjs';
import { map } from 'rxjs/operators';

import { Adv } from './adv.model';

@Injectable({
  providedIn: 'root'
})
export class PlaceService {
  constructor(
    private http: HttpClient
  ) {

  }

  @Cacheable()
  public getAdvs(place: number) {
    return this.http.get<Adv[]>('http://.../api/v1/advs/' + place)
      .pipe(map(advs => advs.filter(adv => adv.landingUrl !== null)));
  }
}

I've also tried without the pipe, but the result is the same.
Could it have something to do with providedIn root and lazy loading?

Thanks for your help.

Question about memory

Thanks for this great library, very useful. I'm wondering how do u know that it does not create a memory leak in your application? I mean when the cache is garbage collected?

@Cacheable on method with Guid as parameter seems not to work (Version: 1.0.7)

The example that is working fine (with id being a Guid.toString()):

@Cacheable()
  getUser(id:string) {
    return this.http
    .get(`api/users/${id}`);
  }

Parameter {id} is resolved to:

GET /api/users/143dffe4-fe9e-40fb-ad49-673f8850bff5

If i know change the string parameter type to Guid like so:

import { Guid } from 'guid-typescript';

@Cacheable()
  getUser(id:Guid) {
    return this.http
    .get(`api/users/${id}`);
  }

In that case for some strange reason, the parameter ${id} that is passed to my api call is resolved to:

GET /api/users/[object%20Object]

Any idea on what i might be doing wrong here?

NOTE: Without @Cacheable, the Guid type is working fine.

Thanks & Cheers!

Cache not working on custom observables

Is this library only compatible with HTTP observables? I have a custom observable in which i control the execution of next and complete methods.

This is my code.

loadApplicationsWithCache(enumValue, {date: "").subscribe(this.onLoadApiComplete, this.onLoadApiError)

@Cacheable() loadApplicationsWithCache(status: someEnumType, date: someObject) : Observable<Map<string, Data>> { return this.loadApplicationsFromAPI.loadApplications(status, date); }

At first, the actual API is being called. The second invocation emits empty map.

throwError() result is cached

Sometimes I like to validate the arguments for the function where the httpClient is used. If the arguments are invalid I use the throwError() function. Currently the logic of your library (which I find to be a great solution that inventively uses the power of typescript) will cache the result of throwError(). I wonder if it could not cache the result.

I did find a way around, which is to instantiate an HttpErrorResponse and pass that to the throwError() function, but I wonder if that should be required.

Thanks for your hard work!

cacheBusterNotifier from another service?

Is it possible to set a cacheBusterNotifier from another service?

Ex.

  • Orders (order.service.ts) is cached for 5 minutes.
  • I create a new order (order-entry.service.ts).
  • When it is successful I want to send a cacheBuster notification to the order.service.ts method for getOrders()

Compilation error when trying to use

As soon as I try to use the option "cacheBusterObserver" in the @Cacheable() decorator, I get a compilation error:

error TS2345: Argument of type '{ cacheBusterObserver: Subject<{}>; }' is not assignable to parameter of type 'ICacheConfig'.
  Types of property 'cacheBusterObserver' are incompatible.
    Type 'Subject<{}>' is not assignable to type 'Observable<void>'.
      Property 'source' is protected but type 'Observable<T>' is not a class derived from 'Observable<T>'.

I have a constant declared with the right name (const productNotifier = new Subject();) in my file.

Note: It is working fine if I just use the plain @Cacheable() without any options.
Note #2: If when it is working fine without the option (using ng serve), I add the option and the Subject and save, I see the compilation error but it says "Compiled successfully" and the code actually work fine! But if I stop ng serve and try to start it again, then it fail....

I am using:
angular 5.2.10
rxjs 5.5.10
zone 0.8.26
typescript 2.6.2

import globalCacheBusterNotifier

Hi,

So it's written on Readme.md that to import globalCacheBusterNotifier do:

import { globalCacheBusterNotifier } from './cacheable.decorator';

but this does not correctly import it. This does:

import { globalCacheBusterNotifier } from 'ngx-cacheable';

Great Library!

Watching changes and busting cache for parameters

I'll give an example code for telling what I need:

export class HeadlinesService extends ApiService<Headline> {
  basePath = 'headlines';

  checkForChanges(slotId: string) {
    this.makara.key('headlines', slotId).subscribe((msg) => {
      // TODO: invalidate cache for `getHeadlines` with this slotId
    })
  }

  @Cacheable()
  getHeadlines(slotId: string): Observable<Headline[]> {
    return this.list2({slot: slotId}).pipe(
      map((listResponse) => listResponse.map(headline => new Headline().cast(headline)))
    )
  }
}

That makara is a socket service that I can bind for the events for data chances in server. I need to run this binding once someone called getHeadlines and then want to bust cache for given slotId when I got an update from makara service. But I couldn't find a way to intercept cacheable to trigger checkForChanges method in first call and then invalidate the cache for given slotId. Can someone give me a tip for that need?

Odd cache/busting behavior in different AWS environments

I have the same application code deployed in (2) different AWS s3 buckets.

In my DEV environment I have a cache busting method when AddEmployee() is invoked. Whenever I return to my employees page it always calls GetEmployees() method with a new API call since I busted the cache.

In my QA environment I have the same cache busting method when AddEmployee() is invoked. Whenever I return to my employees page it always calls GetEmployees() method and returns the cached data, but I busted the cache with the AddEmployee() call.

This is extremely odd behavior. Have you noticed this before?

Service
`@Cacheable({
cacheBusterObserver: employeeCache$.asObservable(),
})
getEmployees(
customerId?: number,
locationId?: number,
): Observable<Employee[]> {}

@cachebuster({
cacheBusterNotifier: employeeCache$,
})
@cachebuster({
cacheBusterNotifier: customerCacheBuster$,
})
public addEmployee(employee: Employee): Observable {}`

Could it be possibly because I have (2) cacheBusterNotifier decorators?

Refresh cache

Hello.

Thanks for his work.
How do you clear (refresh) the cache programmatic?

Thanks

Update rxjs peer dependency

When trying to update my packages via ng update @angular/core I get the following error:

Package "ngx-cacheable" has an incompatible peer dependency to "rxjs" (requires "6.2.0", would install "6.2.2")

Can you update package.json to use any version of rxjs 6?

Something like:

"peerDependencies": {
  "rxjs": "^6.2.0"
},

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.