Reputation: 105
We have a web portal, when user submits a form, after filling all mandatory details, the UI is posting null / empty value for one of the mandatory field – “Name” to the server API.
Name is a textbox (a dojo widget), it has onFocusOut()
method handled. This method performs some checks / serialization / de-serialization and asynchronously updates Name property of main object say "employee".
There is a submit()
method, that is triggered on click of Submit button on this form. This method posts employee object as payload to server API.
ISSUE:
When user types in the name textbox, and without loosing focus clicks on Submit button.
This triggers two async methods (onFocusOut()
and submit()
methods) separated by just a fraction of milli second.
In some rare scenarios, submit()
is posting the employee object to server API, before the Name property of employee object is updated by onFocusOut()
method.
SOLUTION?
Here are different possible solution to this issue –
setTimeout()
to delay triggering of submit()
method. onChange()
instead of onFocusOut()
of text box. submit()
method API post. onFocusOut()
methods. Submit waits for this flag to be set, and then executes API post.What is the optimum solution for such RACE condition? What are the best practices to handle such situation in dojo application?
Upvotes: 1
Views: 194
Reputation: 459
Setting intermediateChanges: true
on your inputs should fix these issues.
https://davidwalsh.name/dijit-intermediatechanges
Upvotes: 0
Reputation: 573
Race conditions are some of the hardest things to fix in JavaScript
, so this is a good question. Your provided solutions for this do point in the right direction, so let me take on three of them and see if I can be of any help with this.
1. Using setTimeout()
to delay the submit()
call
This is definitely one option to prevent such a situation, but there are some caveats to it.
What happens when you wrap your submit()
in setTimeout()
(or rather use it as a callback
in the setTimeout()
) is that the submission gets stacked onto the event queue
.
This way the submit()
will surely get delayed, but it can eventually slow down your code by a fair margin depending on other function calls that get stacked before your submit()
.
I don't know if you are familiar with how JavaScript
handles function calls and events, but there are some very helpful ressources about this topic to be found online. Here is a talk from Phil Roberts about it that helped me understand it a lot better: What the heck si the event loop anyway?
2. Use the onChange()
event instead of onFocusOut()
In my opinion this is by far the better option for your problem.
In React
this method is used to create so called controlled components
. With every change to the input
a function gets called which updates the state
with the new value. This new value is then used to rerender the component (which is very efficient in React
due to the way it detects changes in the DOM
).
There is a good explanation to be found here on SO: controlled VS uncontrolled components
Since you are using some kind of model/object to store the values this could be your best shot.
3. Using a validation function before sending the data
Well, this could be a good solution as well, especially when you design your function as a Promise
, but there are some things to consider before taking this approach.
At first you do would need some kind of model to check if every input taken is correct and meets the expectation. This can be very unsafe regarding the users intention and can lead to unsatisfied user experiences.
And secondly there is the problem that you need to take one more step to successfully post the data to the API
, which always holds the chance to produce a bug/several bugs in your code.
TL:DR; I would go with option 2 since it is the safest among your solutions.
I hope I could be of help with this. :D
Upvotes: 1