[ ] 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:
Skills - @Transaction gets displayed instead of the defined custom action in Redux DevTools. Neither @action nor applyActiondoes work.
Redux DevTools should display [Skills Service] Fetch All.
https://stackblitz.com/edit/akita-todos-app-uiqjdx?file=src%2Fapp%2Fskills%2Fskills-data.service.ts
Am I doing it wrong by defining the custom action in the main service? It's the only place it makes sense for me. Thanks for your support!
:tada: This issue has been resolved in version 1.3.2 :tada:
The release is available on npm package (@latest dist-tag)
Your semantic-release bot :package::rocket:
@NetanelBasal, that was fast, thank you! It seems to have partly fixed the issue. I updated the Stackblitz above to illustrate the remaining part more clearly. Here's a summary of my observations:
@action({ type: '[Skills Service] Fetch All' })
fetchAll() {
this.skillsDataService.getAll().pipe(
tap(entities => {
applyAction(() => {
this.skillsStore.set(entities);
}, { type: '[Skills API] Fetch All Success' });
}),
catchError(error => {
return applyAction(() => {
console.warn(error);
return error;
}, { type: '[Skills API] Fetch All Error' });
})
).subscribe();
}
[Skills Service] Fetch All before making the fake API call and then either Success or Error when receving the response. In DevTools I only seem to get the Success or Error part, @action still seems to get ignored.Diff is empty in DevTools, although the state is populated with the correct data. This might be connected to the previous point.@action for consistency with other decorators?PS. It seems to be a commonly troublesome to link non-redux state management frameworks with the Redux DevTools. NGXS has a similar issue being unable to display Dispatch -> Success || Error in the right order (explanation in the linked comment). It seems that they could be solving this via some lifecycle hooks within the @Action decorator.
@action({ type: '[Products Service] Fetch All', force: true })Successfully fixed everything according to my previous comment. I'd love to hear your thoughts first.
After discussing with the team, we decide that it's not correct to add the force attribute. Action should be dispatched only upon store update. In Redux, for example, when you call [Fetch All], you are usually updating the loading key and change it to true so you can show a spinner.
@NetanelBasal I could successfully solve 1 and 3 by moving everything out of AppComponent.
As for the 2nd, I tend to agree with you and your team. I already modified the Stackblitz and tried this out:
@action({ type: '[Skills Service] Fetch All' })
fetchAll() {
this.skillsStore.setLoading(); <-----------------------------
this.skillsDataService.getAll().pipe(
tap(entities => {
applyAction(() => {
this.skillsStore.set(entities);
}, { type: '[Skills API] Fetch All Success' });
}),
catchError(error => {
applyAction(() => {
this.skillsStore.setLoading(false); <-----------------------------
this.skillsStore.setError(error); <----------------------------
}, { type: '[Skills API] Fetch All Error' });
return error;
})
).subscribe();
}
Now it fires all 3 actions accordingly, so Akita's actions are pretty intelligent already to figure such a case out. Props!
There's only one issue left. The Fetch All action altough fired, it seems to show the wrong Diff (loading from true to false). Feel free to check out the Stackblitz. Thanks for the amazing work and blazing fast answers!
There is no need to call setLoading(). Akita already initializes the store with loading set to true. When you call set() it will automatically set it to false.
You can use the query.selectLoading() method to toggle a spinner in your view. Check out the docs for more information.
If you have any further questions, let me know.
This triggers two questions in my head:
loading set to true without even calling the API request (as in Fetch All)? It somehow feels like magic that perhaps cannot cover 100% of the use cases.Fetch All to get dispatched? I have nothing to update in the store, since loading has already been magically set to true.If you think about it, in 99% of the cases you will call the API when the component is initialized, so basically, we are saving you the setLoading call.
You can always start the loading with false.
export class TodosStore extends EntityStore<State, Todo> {
constructor() {
super( { loading: false} );
}
}
Setting { loading: false } in the initialState of the store does the trick! Then it's just a matter of this.skillsStore.setLoading(true); in the Fetch All action to get it dispatched with the right Diff.
It might be helpful for newcomers to include the lessons learned from this thread into the docs. I would see the following:
You can also initialize the entity store with the loading state set to false:
[paste your code from above]
- Under the Custom action paragraph:
The custom actions will only be dispatched on update of the state.
And perhaps give an example with the Dispatch - Success || Error pattern.
Akita :heart:
Done. Thanks. If you have any further question or feedback, let us know.
Most helpful comment
:tada: This issue has been resolved in version 1.3.2 :tada:
The release is available on npm package (@latest dist-tag)
Your semantic-release bot :package::rocket: