ngxs-labs / async-storage-plugin

⏱ WIP: Async Storage Plugin
MIT License
34 stars 13 forks source link

How Do I Use This With An Auth Guard? It Gives Wrong Values. #72

Open xmarkclx opened 5 years ago

xmarkclx commented 5 years ago

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.

splincode commented 5 years ago

Create example on stackblitz for reproduce

similicious commented 4 years ago

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:

  1. Open the stackblitz
  2. Open Chrome Dev Tools
  3. Click login
  4. Click link ("Navigate to /guarded") Everything works as intended. The state is persisted in IndexedDb.
  5. Refresh the page, while staying on the same route ("/guarded").

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.

ifantom commented 4 years ago

Any news?

kgdiem commented 4 years ago

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.

agustindidiego commented 4 years ago

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

kgdiem commented 4 years ago

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));
});
agustindidiego commented 4 years ago

@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: image

With NgxsStoragePlugin: image

kgdiem commented 4 years ago

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 .

agustindidiego commented 4 years ago

@splincode any thoughts?

developer239 commented 3 years ago

So ... any updates on this? 🤔