Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NGXS Selector observable not getting new state

When i update the state my selector isnt pulling the new values. I have created the selector in my state and i can see the state values being updated, but my selector on my component isn't pulling the newest values. i can see the console log has th newest values and that the state is updating in the browser plugin. however on my componenet the observable does not fire with the newest values.


@State<CompleteUser>(
    {
        name: 'auth',
        defaults: { 
            'user': {
            },
            'userAuth':{
            },
            'usersLocation':{
            },
            'following':[],
            'followers':[],
            'chats':[],
            'favoritePosts':[],
            'favoritePlaces': [],
            'charges': []
        }
    }   
)

export class AuthState {


    @Selector() 
    static user(state: CompleteUser){
        return state.user;
    }

    @Action(
        GetProfile
    )
    GetProfile(
        ctx: StateContext<CompleteUser>,
        uid: any
    ) {
        const state = ctx.getState();
        console.log('Uid ' + uid);
        this.auth.getUsersProfile(
            uid.uid
        ).pipe(
            tap(
                (usersProfile:User) => {
                    console.log('Users profile ', usersProfile);
                    if(usersProfile.alertsAmount && usersProfile.alertsAmount > 0){
                        this.badge.set(usersProfile.alertsAmount);
                    }
                    state.user = usersProfile;
                    ctx.patchState(
                        {   ...state,
                            user: state.user
                        }
                    );
                }
            )
        ).subscribe();
    }
}

my selector observable is as follows

  @Select(AuthState.user) user$: Observable<User>;


    this.liveData = combineLatest(
      this.currentShoots$,
      this.user$,
      this.usersLocation$
    );
 this.pageSub = combineLatest(
      this.liveData
    ).subscribe();

like image 666
Evan Thomas Avatar asked Nov 17 '25 13:11

Evan Thomas


1 Answers

Just return the stream in your action handler. NGXS will subscribe to it for you:

@Action(
    GetProfile
)
GetProfile(
    ctx: StateContext<CompleteUser>,
    uid: any
) {
    const state = ctx.getState();
    console.log('Uid ' + uid);
    return this.auth.getUsersProfile(  // <--- add return statement
        uid.uid
    ).pipe(
        tap(
            (usersProfile:User) => {
                console.log('Users profile ', usersProfile);
                if(usersProfile.alertsAmount && usersProfile.alertsAmount > 0){
                    this.badge.set(usersProfile.alertsAmount);
                }
                state.user = usersProfile;
                ctx.patchState(
                    {   ...state,
                        user: state.user
                    }
                );
            }
        )
    ); // <-- remove subscribe() call 
}

Also, just my opinion, but you could condense your code, you don't actually need to getState... you really only need to patchState:

@Action(GetProfile)
GetProfile({ patchState }: StateContext<CompleteUser>, uid: any) {
  return this.auth.getUsersProfile(uid.uid).pipe(
    tap((usersProfile: User) => {
      if (usersProfile.alertsAmount && usersProfile.alertsAmount > 0) {
        this.badge.set(usersProfile.alertsAmount);
      }
      // state.user = usersProfile; <-- Don't do this
      patchState({ user: usersProfile });
    }),
  );
}
like image 153
Richard.Davenport Avatar answered Nov 20 '25 06:11

Richard.Davenport



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!