angelnikolov / ts-cacheable

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

GlobalCacheConfig.storageStrategy not used in Angular 9? #100

Closed pfleenor closed 3 years ago

pfleenor commented 3 years ago

I've specified GlobalCacheConfig.storageStrategy = LocalStorageStrategy "up top" in my app component yet the @Cacheable decorator doesn't use it. Specifying it directly does work @Cacheable({ storageStrategy: LocalStorageStrategy }) get():{}

Does this working angular?

angelnikolov commented 3 years ago

@pfleenor Can you show me where you've specified it? We have unit tests covering that and they seem to pass. Maybe there's something else going on..

pfleenor commented 3 years ago

Thanks for the quick response. I currently have it in the main app component constructor

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.less']
})
export class AppComponent implements AfterViewInit, OnInit {

  constructor(
  ) {

    GlobalCacheConfig.storageStrategy = LocalStorageStrategy;

}

My test service is injected in the root and uses @Cacheable

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

  @Cacheable()
  get(): Observable<any[]> {
    return this.http.get<foo[]>(url);
  }

The data gets cached, but uses in memory instead of local storage.

angelnikolov commented 3 years ago

I think I know what the issue is here. The AppComponent constructor is invoked at a later stage than the runtime decorators are evaluated. You need to place your global config before Angular bootstraps. Try doing that at the top of the same file where your AppComponent is or even your main.ts file.

angelnikolov commented 3 years ago

@pfleenor Has this helped you?

pfleenor commented 3 years ago

I'm pretty sure, you're correct and what you suggested would fix it. I unfortunately haven't had time to try it and ended up using a different library.

angelnikolov commented 3 years ago

Okay, thanks for the update.

djohle commented 1 year ago

I've been trying very hard to get this global setting to work, but as mentioned before, the runtime decorators are evaluated quite early on in the Angular bootstrapping process.

I have tried putting things in the main.ts, prior to the bootstrapModule call, but even that is too late. In fact, I can get earlier execution than main.ts by declaring the strategy at the top of my AppModule itself, prior to the class declaration. However, even this is after the decorator evaluations :-/

Using some in-browser breakpoints to try and see what is going on, it appears that the decorators are evaluated as the dependency tree of imports is resolved, starting from main.ts itself when it imports AppModule, which imports others, and so on, eventually reaching a class that uses a Cacheable method decorator.

I guess I would have to somehow break the dependency chain that leads from the top to any class that uses Cacheable decorators. That may give a chance to change the global settings before the other components are lazy initialized later in the application lifecycle. I'm not sure that is possible given the current application design, nor would I feel confident that it would always remain that way either.

I'm curious if you have any further thoughts on this situation @angelnikolov .