I have a user object as BehaviourSubject which I observe. I would like to know if a particular value of my user has changed.
My code does not work, and I assume it's because of the way I assign a new object value to my user. I apparently overwrite both the old and new value of my BehaviorSubject, hence I would always compare the same object?
export interface User {
id: string;
username: string;
isBanned: boolean;
subscription?: UserSubscription;
}
export class AuthService {
public readonly user$: Observable<User| undefined> = this.user.asObservable();
user: BehaviorSubject<User| undefined> = new BehaviorSubject<User| undefined>(undefined);
updateUserSubscription(newUserSubscription: UserSubscription): void {
// Here I simply want to update the subscription-Object of my user
this.user.next(Object.assign(this.user.value, newUserSubscription));
}
}
export class MemberService {
user?: User;
private subscription?: Subscription;
constructor(public auth: AuthService) {
// Here I simply want to detect subscription changes
this.subscription = this.auth.user$.pipe(
pairwise(),
filter(users => this.detectSubscriptionChange(users[0], users[1]))
).subscribe(([user1, user2] => { // some code ... })
}
detectSubscriptionChange(user1: User | undefined, user2: User | undefined): boolean {
//subscription status is always the same, as the objects are always the same...
return user1?.subscription?.status !== user2?.subscription?.status;
}
}
Could you tell me how to properly assign new values to my current user object, so I can compare the values in the observable?
Thanks!
CodePudding user response:
If using Object.assign()
to clone, you'd want to put make the "target" in the first parameter an empty object {}
, then "assign" the user object to that new empty object, which represents the new user clone.
const user = Object.assign({}, this.user.value);
Currently you are merely "assigning" the subscription object to the current user.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
In latest JS / Typescript though, the spread operator is much nicer way to clone, and pretty much in line with how you were expecting Object.assign()
to work for cloning:
const user = {...this.user.value});
Not sure how your User
and UserSubscription
models are set up, but if I'm understanding your intent correctly, I think you're going to also new to then directly update the subscription value:
user.subscription = newUserSubscription
this.user.next(user);