Open xmarkclx opened 5 years ago
Create example on stackblitz for reproduce
I've got the same issue. Here is a somewhat minimal reproduction: https://stackblitz.com/edit/async-storage-plugin-guard-issue.
What you need to do:
After refreshing, you're back on the root route ("/"). The guard evaluated to false. When examining the log output you see, that the guard was called before the state from storage could have been restored.
Any news?
I discovered the issue in creating a similar plugin before finding this repo.
The issue is that the store doesn’t yield to the pending, async observable. I worry it’s a blocker but will contribute back any fixes.
I'm having a similar issue. I have found that with async-storage @@UPDATE_STATUS and @@INIT events happens AFTER initial navigation By using storage-plugin, @@UPDATE_STATUS and @@INIT events happens BEFORE initial navigation I'm also seeing that with storage-plugin, events occur even before AppComponent OnInit, but with async-storage they happen after that
Edit I only used a CustomStorageAdapter because I am not using LocalStorage or SessionStorage. You could just seed the values in Local/Session storage too.
I'm having a similar issue. I have found that with async-storage @@UPDATE_STATUS and @@init events happens AFTER initial navigation By using storage-plugin, @@UPDATE_STATUS and @@init events happens BEFORE initial navigation I'm also seeing that with storage-plugin, events occur even before AppComponent OnInit, but with async-storage they happen after that
What I have done thus far to work around this is to use the original NgxsStoragePlugin
with a custom StorageAdapter
that gets seeded in main.ts
before platformBrowserDynamic().bootstrapModule(...)
is called. While this isn't ideal, it works.
For example:
// custom-storage-engine.ts
class CustomStorageEngine {
static store = {}
getItem() {}
setItem() {}
}
// app.module.ts
import { NgxsStoragePluginModule, STORAGE_ENGINE } from '@ngxs/storage-plugin';
@NgModule({
...,
providers: [
{
provide: STORAGE_ENGINE,
useClass: CustomStorageEngine,
},
]
})
// main.ts
import CustomStorageEngine from 'file';
asyncCall.get(arg, (data) => {
CustomStorageEngine.store = data;
platformBrowserDynamic()
.bootstrapModule(CoreModule)
.catch((err) => console.error(err));
});
@kgdiem Thanks for your answer. I'm trying to understand your approach..., so, basically, you are delaying Angular bootstrapping to happen after the your storage engine has the local storage data loaded, right? But you are using the NgxsStoragePlugin, with a storage engine without the async feature. At least in my case, the issue on initialization order only happens on NgxsAsyncStoragePlugin; NgxsStoragePlugin is initialized in correct order. Or maybe I'm a bit lost, I'm not very sure what your asyncCall is, I'm assuming it's a request to a server. If that is the case, we are probably talking about different issues; and in your case, and by using NgxsStoragePlugin, you could probably do the same by making your async call in a APP_INITIALIZER factory or on ngxsOnInit. In my case, I'm not trying to load init data from server, I'm just trying to read a state(with persisted data from localStorage) inside a CanActivate guard on default route, and since because NgxsAsyncStoragePlugin inits after Angular Initial Navigation the state data is not available yet when the CanActivate is executed.
You can see what is going on with this With NgxsAsyncStoragePlugin:
With NgxsStoragePlugin:
I was trying to add support for chrome storage which is async and I couldn’t get my own plugin, or this one, to do @@INIT before the app was initialized.
So what I did was load the initial state outside of Angular and use a custom storage adapter as noted.
Then the adapter maintains updates to state in that static state object whilst making the async calls to chrome.storage without blocking.
On Thu, Apr 23, 2020 at 16:09 agustindidiego notifications@github.com wrote:
@kgdiem https://github.com/kgdiem Thanks for your answer. I'm trying to understand your approach..., so, basically, you are delaying Angular bootstrapping to happen after the your storage engine has the local storage data loaded, right? But you are using the NgxsStoragePlugin, with a storage engine without the async feature. At least in my case, the issue on initialization order only happens on NgxsAsyncStoragePlugin; NgxsStoragePlugin is initialized in correct order. Or maybe I'm a bit lost, I'm not very sure what your asyncCall is, I'm assuming it's a request to a server. If that is the case, we are probably talking about different issues; and in your case, and by using NgxsStoragePlugin, you could probably do the same by making your async call in a APP_INITIALIZER factory or on ngxsOnInit. https://www.ngxs.io/advanced/life-cycle#app_initializer-stage In my case, I'm not trying to load init data from server, I'm just trying to read a state(with persisted data from localStorage) inside a CanActivate guard on default route, and since because NgxsAsyncStoragePlugin inits after Angular Initial Navigation the state data is not available yet when the CanActivate is executed.
You can see what is going on with this With NgxsAsyncStoragePlugin: [image: image] https://user-images.githubusercontent.com/4682822/80142390-70ebd300-8581-11ea-8753-e1deb8bda413.png
With NgxsStoragePlugin: [image: image] https://user-images.githubusercontent.com/4682822/80144598-2d936380-8585-11ea-97f6-be57d839596c.png
— You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub https://github.com/ngxs-labs/async-storage-plugin/issues/72#issuecomment-618638073, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADEAQ5J4GJXZVHBTOSYPISTROCOAXANCNFSM4HHAIPSQ .
@splincode any thoughts?
So ... any updates on this? 🤔
It seems to always return the default value for me, when I console.log the output on the Auth Guard, instead of the one saved. But Redux DevTools shows it loaded the correct value on the INIT state though.