-
Notifications
You must be signed in to change notification settings - Fork 26.6k
Open
Labels
area: coreIssues related to the framework runtimeIssues related to the framework runtimecross-cutting: resourceIssues related to the newly introduced resource / httpResourceIssues related to the newly introduced resource / httpResource
Milestone
Description
Which @angular/* package(s) are relevant/related to the feature request?
core
Description
If we want to use cached data on resources, we have to use startWith
in our observables, but that's not great, because we loose the functionality of isLoading
, as that will be immediately true.
Currently defaultValue would be a great place for that, but defaultValue doesn't accept dynamic values (callback fn that can return a different value everytime it's called), and this makes it painful to have resources that use cache data.
class UsersListStore {
private readonly currentCachedItems = computed(() => {
return this.usersGlobalStore.getEntitiesByFilters(this.currentFiltersPayload());
});
// WITHOUT REACTIVE DEFAULT VALUE, needs rxjs operators
readonly usersRes = rxResource({
params: () => this.currentFiltersPayload(),
stream: ({ params: payload }) => {
return this.usersApiService.getUsers(payload).pipe(
tap(result => {
this.usersGlobalStore.storeResultsAndFilters(result.items, payload);
}),
startWith({ items: this.currentCachedItems(), total: this.currentCachedItems().length }),
filter(x => x.total > 0)
);
},
});
}
Proposed solution
class UsersListStore {
private readonly currentCachedItems = computed(() => {
return this.usersGlobalStore.getEntitiesByFilters(this.currentFiltersPayload());
});
// WITH REACTIVE DEFAULT VALUE, no need for rxjs operators
readonly usersRes = rxResource({
defaultValue: () => ({
items: this.currentCachedItems(),
total: this.currentCachedItems().length,
}),
params: () => this.currentFiltersPayload(),
stream: ({ params: payload }) => {
return this.usersApiService.getUsers(payload).pipe(
tap(result => {
this.usersGlobalStore.storeResultsAndFilters(result.items, payload);
})
);
},
});
}
Alternatives considered
We can use a getter but that's not great 👀
class UsersListStore {
private readonly currentCachedItems = computed(() => {
return this.usersGlobalStore.getEntitiesByFilters(this.currentFiltersPayload());
});
get resourceDefaultValue() {
return {
items: this.currentCachedItems(),
total: this.currentCachedItems().length,
};
}
// WITH REACTIVE DEFAULT VALUE, no need for rxjs operators
readonly usersRes = rxResource({
defaultValue: this.resourceDefaultValue,
params: () => this.currentFiltersPayload(),
stream: ({ params: payload }) => {
return this.usersApiService.getUsers(payload).pipe(
tap(result => {
this.usersGlobalStore.storeResultsAndFilters(result.items, payload);
})
);
},
});
}
msmallest
Metadata
Metadata
Assignees
Labels
area: coreIssues related to the framework runtimeIssues related to the framework runtimecross-cutting: resourceIssues related to the newly introduced resource / httpResourceIssues related to the newly introduced resource / httpResource