DanWahlin / Observable-Store

Observable Store provides a simple way to manage state in Angular, React, Vue.js and other front-end applications.
MIT License
637 stars 121 forks source link

SetState method is not working #173

Closed hamidh2 closed 3 years ago

hamidh2 commented 3 years ago

@DanWahlin

I'm using the setState method but it seems it doesn't work. actually, always the state value is equal to the default value!

this.setState(
          { currentUser: loggedInUser },
          UserStoreActions.userLoggedIn
        );

after setState when I'm subscribing to my state class state value is always equal to the default value!!

  constructor(private authService: AuthService) {
    this.subs.sink = this.authService.stateChanged.subscribe((state) => {
      console.log('user panel sate', state);
      this.user = state.currentUser ?? null;
    });
  }
DanWahlin commented 3 years ago

If you can put a Stackblitz (https://stackblitz.up) demo together that demonstrates your issue I'm happy to look into it more. We use setState all the time without any issues so I'd need a demo that reproduces what you're seeing.

hamidh2 commented 3 years ago

If you can put a Stackblitz (https://stackblitz.up) demo together that demonstrates your issue I'm happy to look into it more. We use setState all the time without any issues so I'd need a demo that reproduces what you're seeing.

okay, btw I have another problem would you take a look at it

Is there a way to use the state of a class in a synchronous way because there is a limitation in some places in angular for using asynchronous value and we should provide the data with synchronous methods for instance we should provide such thing in interceptors, I tried to get rid of state asynchronous behavior with a trick but it didn't work I created a method in my state class and I tend to call it in other places but it always returns the default value!!! plz help to overcome this issue

  public getUserState(): UserState | null {
    const state = this.getState();
    console.log('state in auth service', state);
    if (state && state.currentUser) {
      return state;
    }
    return null;
  }

FYI @DanWahlin

DanWahlin commented 3 years ago

Calling getState() should always return the latest state value. Based on what you're saying here and the other issue you mention I suspect something else is going on. Once you can put together a demo to reproduce the issue I'll take a look as soon as I can.

I'd also run the supplied demos if you haven't already because they show setState and getState working correctly.

hamidh2 commented 3 years ago

@DanWahlin
I tried all the stuff in an experimental project and setState worked but I dunno why it loses it's when I'm reloading the page!! plz check this link https://stackblitz.com/edit/angular-ivy-icrmc4?file=src/index.html btw I recorded a video from my local machine hope it help you for understanding my issue

https://user-images.githubusercontent.com/41614055/124891304-19068400-dfee-11eb-82c0-06a9047ab56d.mp4

DanWahlin commented 3 years ago

I wish everyone was as detailed as that. Thank you...that helps. 😀

Observable Store is a client side only state management solution. All state is stored in memory so if the app is reloaded in the browser all of your state is reinitialized again. That's normal for these types of client state solutions. It's used to manage state while the app is running but isn't designed to store state across user sessions as mentioned.

If you want the state to be stored across page loads (refreshes for example) you'll have to handle that part yourself and then pass that saved state to Observable Store when the app first loads. State for a user could be stored in localStorage (https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) for example. If the state needs to be stored for a user to access anywhere, then you'd have to pass the state to an API which then handles storing it in some type of database or other store.

hamidh2 commented 3 years ago

@DanWahlin Thank you for the description. but I think if the package has an option for storing data in local or session storage it would be nice because sharing data in the whole application is possible with normal observable and saving data in a store like local storage and manage by this package would be kinda added value

DanWahlin commented 3 years ago

Thanks. That's something I'll consider for future releases. The challenge is that there are limitations on localStorage size, security challenges that can come up and more (that's why most state management solutions don't handle that out of the box). Right now it's not something I'm planning to build, but I'll add it to the list for consideration in the future. I appreciate your feedback.

hamidh2 commented 3 years ago

Thank you @DanWahlin I confess that you reply very quickly and it was very awesome for me! hope to provide that part for the package very soon

DanWahlin commented 3 years ago

No problem. Sorry I don't have that feature now. I doubt it'll ever be in the core package but could potentially be an add-on package some day.