I've recently run into a small issue with race conditions in my code. I am using Knockout.Js to gather some information to be displayed to the user.
The trouble occurs when a drop down needs to be generated before the value can be selected. Normally the drop down list is smaller than the other request and will win the race, and thus causing no problems. However I have seen some situations in my application, on slower internet connections, where the list loads secondly. Below is an example. If there is no option in the list for the value, it cannot be selected, and to the user appears as though there was not one selected.
Using setTimeout
I've simulated this experience. You can swap the two values to see the "success" scenario.
function ViewModel() {
var self = this;
self.UserName = ko.observable();
self.UserGroup = ko.observable();
self.GroupList = ko.observableArray();
self.LoadUserGroups = function() {
//Ajax call to populate user groups
setTimeout(function() {
response = "Red Team,Blue Team,Green Team".split(",");
self.GroupList(response)
}, 2000) /// SWAP ME
}
self.LoadUserInformation = function() {
setTimeout(function() {
response = {
UserName: "John Pavek",
UserGroup: "Blue Team"
};
self.UserName(response.UserName);
self.UserGroup(response.UserGroup);
}, 1000) // SWAP ME
}
self.Load = function() {
self.LoadUserGroups();
self.LoadUserInformation();
}
self.Load();
}
ko.applyBindings(new ViewModel())
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
User Name:
<input data-bind="value: UserName" /> User Group:
<select data-bind="options: GroupList, optionsCaption: '--Pick a Team--', value: UserGroup"></select>
What could I add to my code, Vanilla or knockout to prevent this issue from occurring without slowing down the entire experience?
What's happening is that the select is overriding
UserGroup
when the valueLoadUserInformation
tries to set isn't in the options list. But you can usevalueAllowUnset
to tell it not to worry about unknown values. Then it won't override.