Search code examples
angularngrxngxs

How to avoid loops in NGRX or NGXS


I have a component like user-personal-details.component.ts. Which stays in sync with user stored in Store

@Select() user$: Observable<IUser>;
user:IUser;
ngOnInit() {
  this.user$.subscribe((user:IUser)=>{
    this.user = user;
    this.form.form.patchValue(user);//LINE A: fill the form using user data
  };
}

This component has a form to fill details about the user. There is no save button, everytime user type of any of these component, I detect changes via

this.form.valueChanges.debounce(2000).subscribe((formData)=>{
    this.store.dispatch(new UpdateUser(formData));//Line B
})

and dispatch an Action named UpdateUser to store changes in Store.

Problem:

Problem is when user will type something, it will dispatch action to change User in store (Line B). Since component is subscribed to user in store, Line A will be called again. Which in turn, patch the form hence calling Line B. Thus making it a cycle.

One way to avoid this is mutate the state when form changes because that will not fire an action and hence line B will not be called. But I think thats not recommended in Redux.

Can someone suggest a more elegant way to deal with this problem?

Note: I am using NGXS for this but I guess it shouldn't make a difference.

Edit: Since the question was downvoted, I made a big edit to this question to make the problem minimal.


Solution

  • I believe that you should populate the form with user from store only once at the beginning when form is loaded. Any later change of the user form shouldn't change the form anymore. The form will be source of truth in that case. It will not sync data from the store anymore but to the store.

    You can use take operator for that:

    this.user$.pipe(take(1)).subscribe((user:IUser)=>{
      this.user = user;
      this.form.form.patchValue(user);//LINE A: fill the form using user data
    };
    

    BTW also consider using form plugin for NGXS