ngneat / cashew Goto Github PK
View Code? Open in Web Editor NEWπΏ A flexible and straightforward library that caches HTTP requests in Angular
Home Page: https://www.netbasal.com
License: MIT License
πΏ A flexible and straightforward library that caches HTTP requests in Angular
Home Page: https://www.netbasal.com
License: MIT License
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[X] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
Currently, new HttpParams is called hidden away inside the lib without the possibility to set the encoder
being able to set an encoder (at least globally) as HttpParams default encoder does not encode/decode params as expected:
angular/angular#18261
have symbols such as + in the param value
As the lib abstracts away the creation of http params, a way to correct the encoding is needed.
Angular version: 4+ (tested on 5,6,7,8,9)
Browser:
all browsers
For Tooling issues:
- Node version: all versions
- Platform: tested on mac, linux, windows
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ X] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
When doing a http POST with HttpParams calls wrong url.
The called url is
https://localhost:4200/api/search?updates=%5Bobject%20Object%5D&cloneFrom=&encoder=%5Bobject%20Object%5D&map=null
Can pass a variable with HttpParams type into WithCache and correct url is called. HTTP call functions as normal. Cache is stored as per cashew localstorage.
Given a this test code.
...
params = new HttpParams();
params = params.append('context', context)
return new Promise((resolve, reject) => {
this.http.post(url, payload, withCache({...params})).subscribe((result) => {
resolve(result);
}, (error) => {
reject(error);
});
});
Cashew clearly tries to convert HttpParams to query string. Is there a specific object I should be passing?
Angular version: X.Y.Z
8.2.3
Browser:
- [X ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: XX
- Platform:
Others:
Using Local Storage
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[X] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
The following is not accepted syntax
const someId = 0;
withCache({ key: someId })
forcing me to use withCache({ key: `${someId}` })
or withCache({ key: ''+someId })
This syntax to be accepted
const someId = 0;
withCache({ key: someId })
Developer experience
Angular version: X.Y.Z
Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: XX
- Platform:
Others:
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[x] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
I am not able to change the storage provider from localStorage to something else
A exposed HttpCacheStorage provider to modify it. We for example use CapacitorStorage.
Angular version: 14
Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: 17
- Platform: Mac
Others:
[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
I'm using useHttpCacheLocalStorage
to cache with LocalStorage
and the request results are being cached with key '@cache-example'.
The culprit seems to theese 2 lines, where i think createKey()
there shoud not be there:
When I try to clear all cached entries with HttpCacheManager
clear(), it iterates all the keys and ads a new '@cache' prefix making the previous key @cahe-@cache-example
:
Localstorage entries related to cached data should have been deleted.
It is possible to reproduce using the playground app with useHttpCacheLocalStorage
.
Angular version: 14.0.1
Cashew version: 3.0.0
Browser:
- [x] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
I suggest skip auto repeat request after invalidate the cache until first call by user the call.
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[x] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
We got a repeat all requests after delete some key/bucker from the cache manager.
Add config for prevent auto repeat cached requests
Angular version: 9.1.2
Cashew version: 1.3.2
[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
The TypeScript compiler throws a TypeError when one is testing a service that uses the CacheBucket.
Example service:
@Injectable()
export class DocumentService {
private _documentBucket = new CacheBucket();
constructor(private http: HttpClient) {}
/**
* Returns a cached document
* @param documentId
*/
getDocument(documentId: string): Observable<EbDocument> {
return this.http.get<EbDocument>(`/api/documents/${documentId}`, {
context: withCache({
ttl: 10_000,
bucket: this._documentBucket
})
});
}
}
Which causes the following in a Spectator driven test that is executed by Jest (we do not use the createHttpFactory here since we explicitly want to validate the cache context):
describe('DocumentService', () => {
const createService = createServiceFactory<DocumentService>({
service: DocumentService,
mocks: [HttpClient]
});
it('should call the endpoint', done => {
const spectator = createService();
const httpClient = spectator.inject(HttpClient);
httpClient.get.andReturn(of({}));
spectator.service
.getDocument('documentId')
.subscribe(() => {
expect(httpClient.get).toHaveBeenCalledWith('/api/documents/documentId', {
context: withCache({
ttl: 10_000,
bucket: new CacheBucket()
})
});
done();
});
});
});
TypeError: Constructor Set requires 'new'
at CacheBucket.Set (<anonymous>)
Since CacheBucket only extends Set without applying anything else, it is possible to fix this issue by typing the CacheBucket as Set here, but this is dangerous since the implementation may change over time.
We should fix this, so we have a happy compiler.
Angular >= 12 with TypeScript 4.3.5 and Cashew 2.3.2.
Angular version: 12.2.16
Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: XX
- Platform:
Others:
#4 I'm submitting a...
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[x ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
HttpCacheStorage provides a synchronous interface.
Allow for caching in async storage such as IndexedDB and other async storage options.
I'm creating an Ionic/Capacitor application and I would like to be able to use Capacitor storage to work around the 5mb localStorage limit. I'm not able to do this because all of the Storage methods return promises.
All
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[X] Support request
[ ] Other... Please describe:
When you use the withCache()
function in a HttpClient
method, it needs to be assigned to the context
option. How do you add something else to the HttpRequest
context ?
[ ] Regression (a behavior that used to work and stopped working in a new release)
[x ] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
The following code works fine in development mode (ng serve), but not in Prod mode (ng serve --prod=true):
{ provide: HTTP_CACHE_CONFIG, useValue: { ...defaultConfig, ...config } }
When I tried to change code as below, then I am losing config variable (but worked fine in --prod=true flag)
{ provide: HTTP_CACHE_CONFIG, useValue: { defaultConfig} }
It must accepted both values in production mode.
Run local with prod mode -
ng serve --prod=true , then monitor below methods (network call), it is calling API in each click event
loadTodos() {
this.http.get('https://jsonplaceholder.typicode.com/todos', withCache()).subscribe(res => {
console.log(res);
});
}
It should cache API calls in production mode as well
Angular version: 7.2.16
Browser:
- [x ] Chrome (desktop) version 84.0.4147.125
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: 12.16.1
- Platform: Windows
Others:
@angular-devkit/architect 0.13.10 (cli-only)
@angular-devkit/build-angular 0.13.10
@angular-devkit/build-ng-packagr 0.13.10
@angular-devkit/core 7.3.10 (cli-only)
@angular-devkit/schematics 7.3.10 (cli-only)
@angular/cli 7.3.10
@ngtools/json-schema 1.1.0
@ngtools/webpack 7.3.10
@schematics/angular 7.3.10
@schematics/update 0.13.10 (cli-only)
ng-packagr 4.7.1
rxjs 6.5.5
typescript 3.2.4
webpack 4.29.0
[ ] Regression (a behavior that used to work and stopped working in a new release)
[x ] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
const params = {brands: [1,2]};
this.http.get (url, {... {params: {... params}}});
URL?brands=1&brands = 2
const params = {brands: [1,2]};
this.http.get (url, {... {params: {... params}}});
URL?brands=1
const params = {brands: [1,2]};
this.http.get (url, {... {params: {... params}}});
URL?brands=1
Angular version: 8.2.14
Browser:
- [x ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: XX 10.21
- Platform: Windows
Others:
When I add an HttpCacheInterceptorModule to app.module.ts some of my requests stop working correctly,
namely params array cease to work correctly
"@angular/common": "~ 8.2.14",
example:
const params = {brands: [1,2]};
this.http.get (url, {... {params: {... params}}});
url?brands=1&brands=2
with HttpCacheInterceptorModule
url?brands=1
[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
Can not add HTTP header with withCache
export interface HttpOptions {
headers: HttpHeaders;
params?: HttpParams;
}
I think this kind of interface would be better to easy adding headers or parms with withCache function
Angular version: 11.2.9
Browser:
For Tooling issues:
Others:
[ ] Regression
[x] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
When you build a project with the ng build --prod command, the library stops working.
Library caches queries in prod mode
AOT:true
ivy:false
HttpCacheInterceptorModule.forRoot({
strategy: 'explicit',
ttl: 10 * 10000,
responseSerializer(body) {
return cloneDeep(body);
}
})
return this.http.get(this.API + '/auth/user/', withCache({
cache$: true,
key$: USER_CACHE_KEY
}))
Angular version: 8.0.1
Browser:
- [x] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [x] Firefox version XX
- [x] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: XX
- Platform:
Others:
Implicit strategy seems to require using withCache()
In 2.0.1 cache-interceptor.ts has this:
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const context = request.context.get(CACHE_CONTEXT);
if (context === undefined) {
return next.handle(request);
}
...
If I have not misunderstood the logic of the code, this will always return the request unchanged unless you use withCache()
.
In 1.3.2 httpCacheInterceptor.ts had a different logic and starts asking CacheGuard
.
[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
If an http request errors (any 400/500 response), the request remains in the queue and cannot be cleared but emptying the cache.
And non successful response should not be cached and should be cleared from the queue.
this.http.get('http://notarealurl.test', withCache())
For instance, when requesting an endpoint that is protected by authorisation, the first user may not be able to access the resource (returning 403). This user logs out and another user logs in. The request is retried, but the original request is issued including the Authorization header from user 1, not the new request with the new Authorization header.
I suggest changing the interceptor like this (https://github.com/ngneat/cashew/blob/master/projects/ngneat/cashew/src/lib/httpCacheInterceptor.ts#L37):
tap({
next: event => {
if (event instanceof HttpResponse) {
const cache = this.httpCacheManager._resolveResponse(event);
this.httpCacheManager._set(key, cache, +ttl);
}
},
// Delete the item from the queue when the request completes
// This will ensure it is not replayed if the request is cancelled or it errors
complete: () => {
queue.delete(key);
}
}),
Angular version: 9.1.3
@ngneat/cashew 1.1.3
Browser:
- [x] Chrome (desktop) version 81
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: 12
- Platform: Mac
Others:
[ ] Regression (a behavior that used to work and stopped working in a new release)
[X] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
Angular CLI reports that @ngneat/cashew has a CommonJS or AMD dependency that can cause optimization bailouts.
Warning: C:\Projects\XYZ\src\app\core\core.module.ts depends on '@ngneat/cashew'. CommonJS or AMD dependencies can cause optimization bailouts.
For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies
I guess that Angular CLI shouldn't complain about @ngneat/cashew being a CommonJS or AMD dependency.
I just updated cashew from last 1.x version latest 2.x version and Angular CLI started to produce this warning.
Angular version: 12.1.1
Angular CLI version 12.1.1
Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: 14.15.5
- Platform: Windows
Others:
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[x] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
I've seen in the doc that you can use withCache()
in HttpClient methods like .get()
, .post()
, etc. But when trying to be used on .request()
https://angular.io/api/common/http/HttpClient#request, is not supported (or maybe I have not found the way)
Support to use withCache()
on .request()
method
Being able to use cashew
with an abstraction method to do http requests
[ ] Regression (a behavior that used to work and stopped working in a new release)
[X] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
I have a route with a guard and a resolve. The same service is called in both and the called method is a HTTP request with caching enabled (useHttpCacheLocalStorage).
The service
getLeagues(): Observable<League[]> {
console.log('getLeagues')
return this.http.get<League[]>(`${LEAGUES_API}`,
withCache()
)
}
The resolve (the tap operator is just to understand why it's not working)
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<League[]> | League[]{
console.log('call getLeagues from resolve')
return this.leagueService.getLeagues()
.pipe(
tap(val => console.log(`${val}`)),
);
}
The behavior is wrong when cache is empty
Cache is empty
Call getLeagues from guard => cache is populated
Call getLeagues from resolve => the tap operator is not called
Refresh the app (cache is already populated)
Call getLeagues from guard
Call getLeagues from resolve => the tap operator is called
Angular version: 11.0.2
Browser:
- [X] Chrome (desktop) version Chromium to 87.0.4280.67
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
[x] Feature request
Currently we have to use importProvidersFrom(HttpCacheInterceptorModule.forRoot())
in order to use the lib on apps that are built with standalone bootstrap api-s.
Also, we need to use withInterceptorsFromDi()
in the provideHttpClient()
in order for the cache interceptor to be registered as it's a class based interceptor.
Add some new api-s that export the providers using sth like:
provideHttpCache()
And inside it we can add all the providers needed for the lib to work,
So basically we can just add sth like this (that we also can reuse in the module that the lib already uses, so no duplicated code):
export const provideHttpCache = (config: Partial<HttpCacheConfig> = {}) => {
const providers: (Provider | EnvironmentProviders)[] = [
{ provide: HTTP_CACHE_CONFIG, useValue: { ...defaultConfig, ...config } },
{ provide: KeySerializer, useClass: DefaultKeySerializer },
{ provide: HttpCacheStorage, useClass: DefaultHttpCacheStorage },
{ provide: TTLManager, useClass: DefaultTTLManager },
{ provide: HttpCacheGuard, useClass: DefaultHttpCacheGuard },
{ provide: HttpCacheVersions, useClass: DefaultHttpVersions },
HttpCacheManager,
RequestsQueue,
RequestsCache,
config.skipInterceptorDeclaration
? []
: provideHttpClient(withInterceptors([httpCacheInterceptor])) // --> This is not recommended.
config.skipInterceptorDeclaration
? []
: { provide: HTTP_INTERCEPTOR_FNS, useValue: httpCacheInterceptor, multi: true } // --> Maybe we can do this in the future
];
return makeEnvironmentProviders(providers);
};
Better align with the direction of Angular libs.
[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
I am not seeing HttpHeaders beeing saved or received in cache.
HttpHeaders should be serialized as HttpHeaders otherwise a .get()
wont longer work in interceptors.
We have request and correlation ids set in backend in response headers that I put into the response body for better access in templates. This is done in an interceptor.
Angular version: 17
Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: 20
- Platform: Mac
Others:
[x] Documentation issue or request
Cashew caches HTTP requests and only updates the cached data when it is deleted/expired.
Cashew retrieves cached data, returns it to the user, and then makes an HTTP request to update the cached data. Once the updated data is available, Cashew pushes it to the user.
I am using @ngneat/cashew to cache HTTP requests in my Angular project.
I would like to know if it is possible to implement the cache and refresh strategy, as exemplified on the angular.io page link
I tried looking for information in the documentation and code, but I could not find any.
// cache-then-refresh
if (req.headers.get('x-refresh')) {
const results$ = sendRequest(req, next, this.cache);
return cachedResponse ?
results$.pipe( startWith(cachedResponse) ) :
results$;
}
// cache-or-fetch
return cachedResponse ?
of(cachedResponse) : sendRequest(req, next, this.cache);
Angular version: 15.2.2
Browser:
- [x] Edge version 118
For Tooling issues:
- Node version: v18.17.0
- Platform: Windows
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[ ] Feature request
[X] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
Currently it's not quite easy to figure out how Cashew will behave in tests. What it's interactions are with HttpClientTestingModule
, and verifications on this. It is also not clear how it will behave in regards to fakeAsync
, tick
and their interactions with TTL.
Some documentation about these interactions would be most helpful in testing code that relies on Cashew.
When testing code using cashew and using HttpClientTestingModule
it can be hard to know exactly how to use the primitives such as flush
, and how to properly do assertions on the HttpTestingController
[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
When using it with Angular Universal the localStorage is undefined.
Angular version: 12.0.4
[x] Other... Please describe:
Currently you have to decide overall what the storage pattern will be (whether memory, local storage, custom, etc...)
I was curious if anyone has asked for the ability to pass a storage parameter in the withContext
so you could declare a storage target specific to different API calls.
The reason I bring this up is that there might be some non sensitive API calls that return application configuration that would be a good candidate for localStorage where I get the benefit of multiple browser tabs sharing that information. Whereas I might have some other data I'd like to cache in the browser but just inMemory that I wouldn't want to leave in localStorage.
Perhaps the answer would be to write a custom storage provider but I was just curious if anyone had asked for something like this or if there's a strong reason why its very difficult or not a good idea.
Great library btw. Thanks for your time!
[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
Currently parameterCodec in config as it is shown in the readme does not work fΓΌr AOT compilation. The problem is the constructor call of new CustomHttpParamEncoder() in @NgModule.
possibility to give CustomHttpParamEncoder to config so the request params are correctly encoded / decoded.
add parameterEncoder to config and compile with AOT.
Angular version: 7,8,9
Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: v14.1.0
- Platform: Mac
Others:
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[ ] Feature request
[x] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
It seems that v4 dropped support for module based apps: 3e92e8e
It does not expose HttpCacheInterceptorModule
and useHttpCacheLocalStorage
anymore. And the docs have been updated on how to use cashew in standalone Angular apps. There are no docs on how to use cashew in non-standalone apps.
The docs describe how to use cashew in non-standalone module based angular apps.
Many (most?) Angular apps are not standalone and therefore they should be supported.
@ngneat/cashew 4.0.0
Cached responses have a fixed expiry date, expressed in the form of a time-to-live which is added to the date/time the response is saved to the cache. If I make a request with a ttl of one hour, then request the same url five minutes later with a ttl of one minute, the cached response is returned and continues to be returned for a further 55min. The current behaviour honours the concept of time-to-live and is similar to the browser cache but it doesn't suit all use cases.
I expected the ttl to be updated when the same url is requested with a different ttl. I also expected the cached response to be deleted when the requested ttl is less than the elapsed time since the last response was cached.
The above is one way to implement my desired behaviour, another would be to specify cache "maxAge" in milliseconds or "since" date/time in addition to ttl. If max age is specified and ttl is very large, responses would effectively be cached indefinitely, only being deleted when a more recent response is requested.
I'm working on a dashboard app with back-end data that is updated in bursts. I request aggregate data with a ttl of 1 hour because it is expensive to compute, but I also monitor the back-end for new data every 5 mins. When new data is received on the back-end I would like to lower the ttl/maxAge until the burst is complete, then gradually increase it again. There are multiple pages of views and corresponding queries that can be performed, so expiring the entire cache in one hit would not be a good strategy.
Would it make sense to add reload$ property to the withCache params interface? When it will be set to true, stored data for the specific keys will be replaced with the newest. Now probably the one way to achieve that is manually removing a specific key with CacheManager before making a request.
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[X] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
Angular 13 is used for the project currently.
The README.md
doesn't give any information about supported angular versions
I am aware that the library package.json
has a peer dependency towards angular 13+ - so it's possible the library works just fine with angular 14 (which is really cool and should be adopted by more angular 3rd party libs π )
But I'm currently mapping out the migration path for a large project with a lot of dependencies, and I was wondering if cashew
has already been tested with angular 14? Maybe somebody has experience migrating this already?
Then I thought it would be nice to actually provide angular compatiblity information in the main readme of the repository.
Alternatively upgrading the whole library to angular 14 would also resolve my question, of course π
n/a
Angular 14 was released on June 02, 2022 and is becoming adopted more and more widely. In November we already expect ng15 to hit the road.
Cashew is one of the last libraries for my specific ng 14 upgrade that is not confirmed yet to be ng 14 compatible.
Angular 14
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[x] Support request
[ ] Other... Please describe:
I currently use a standard request to an API that needs Headers:
return this.http.get<ITideResults>(this.tideServiceURL, { headers: this.headers })
Expected to be able to continue to use Headers as well as caching :-)
Following the docs I tried:
return this.http.get<ITideResults>(this.tideServiceURL, { headers: this.headers }, withCache())
however realise get() expects 2 arguments and not 3. Not sure how to work out where to put withCache() if I'm also using headers.
The API I'm using has usage limits so I'd like to cache the request (for 7 days) on the users device on the first use so as to limit hitting the API ... Cashew seems to be a great option for this use case ;-)
Angular version: 9.1.0
@ngneat/cashew 1.1.4
Browser:
- [x ] Chrome (desktop) version 80.0.3987.163
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: v12.13.0
- Platform: Mac
[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
This bug was first reported here: https://issueexplorer.com/issue/ngneat/cashew/27
I have narrowed it down further.
Cacheable requests are saved in a queue by the http interceptor. When a response is received it is shared with all subscribers and then, when the request completes, it is deleted from the queue inside a finalize operator so subsequent requests will be served from the cache.
But, if the request is called again by a subscriber of the initial request, the queued request is returned as an empty observable, after the response has been emitted but before it completes.
The http interceptor should return the cached response, not the queued request, after the response is received.
It comes down to this:
this.http.get(url).pipe(
switchMap(() => this.http.get(url))
).subscribe(() => console.log(`Never happens`))
I will submit a pull request with a demonstration of this bug and a suggested fix.
This situation typically comes up when using cacheable http requests in guards and route handlers. This was the case for me and the two people who posted on issueexplorer.
Angular version: 12.0.1, 12.2.8, 10.2.3
cashew versions 1.3.1, 2.3.1
Browser:
- [x] Chrome (desktop) version 94
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [x] Firefox version 93
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[ ] Feature request
[X ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
I've been looking for a compatability matrix which would map the library's version against the supported Angular versions.
Something like the following, this example is taken from RxAngular library.
None
Help new users of the library to pick the correct version for their application.
Angular version: X.Y.Z
Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: XX
- Platform:
Others:
[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
Warning: Unable to fully load /Users/x/WebstormProjects/project/node_modules/@ngneat/cashew/lib/httpCacheStorage.d.ts
for source-map flattening: Circular source file mapping
dependency:/Users/x/WebstormProjects/project/node_modules/@ngneat/cashew/lib/httpCacheStorage.d.ts.map ->
/Users/x/WebstormProjects/project/node_modules/@ngneat/cashew/lib/httpCacheStorage.d.ts.map
No warns
npm run start
with "@ngneat/cashew": "^1.3.0",
in the package.json when using Angular 10.Angular version: 10.0.8
Browser:
For Tooling issues:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.