How to avoid loops in NGRX or NGXS

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


user-personal-details.component.ts


user


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


user


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.


Action


UpdateUser


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.


user



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.




1 Answer
1



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:


take


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






Thanks for your response. I can't do that. I have a reset button which when clicked, discard all the user changes, and fills the forms with fresh server verison of the form.

– dasfdsa
Sep 10 '18 at 15:47






@dasfdsa why you cant do that? So there is another button which fills data to the form and since then form is again source of truth. Its the same situation.

– Martin Nuc
Sep 10 '18 at 19:55






Thanks again. 1. reset button fetches the fresh data from server and stores it into the store. 2. Since component has subscribed to this.user$ it will again patch the form. 3. Since the form has been patched this.form.valueChanges will run its callback and dispatches the action to change the store. 4. this callbac.user$ subscription callback will run....and the cycle continues. Sorry for the late response.

– dasfdsa
Sep 14 '18 at 15:30






If I do this.user$.pipe(take(1)). My form will not be patched like its happening in step 2.

– dasfdsa
Sep 14 '18 at 15:31






@dasfdsa when clicking reset it should reload the user and patch the form itself with reloaded data. You could event have a method refreshFrom which reload store from server and patches the form. But dont let the component listening for data all the time imho.

– Martin Nuc
Sep 14 '18 at 15:35


refreshFrom



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)