I'm getting and object from the back-end with some properties and use AngularJS to put them into input fields (inputs, textareas, checkboxes, dropdown lists).
These properties are in some cases a text value, in some a number value but can also be null
, undefined
, false
or ""
.
I clone this object and then check if user is making any modifications to each of these values by comparing the old (stored) value with new (current) one.
I don't want to use the ng-dirty
class for detecting a change because it does not disappear when you go back to the previous value after a prior modification (e.g. when using Ctrl+Z).
I thought this task would be simple however I'm getting trouble with this due to ambiguous nature of JS values.
Of course I treat every of these:
null
undefined
false
""
an "empty value" because for user "an empty field is an empty field", regardless of what the model stores underneath. So, for example, a change from undefined
to ""
is not really a change.
So far I've got this:
$scope.areDifferent = function (oldValue, newValue) {
var a = true, b = true;
if (oldValue === null ||
oldValue === undefined ||
oldValue === false ||
oldValue === "") {
a = false;
}
if (newValue === null ||
newValue === undefined ||
newValue === false ||
newValue === "") {
b = false;
}
if (!a && !b) {
return false; // both values are "empty"
}
else if (a != b) {
return true; // one of the values is "non-empty"
}
else {
return oldValue != newValue; // compare the value of "non-empty" properties
}
}
But I'm curious if this is correct (are there any non-covered edge cases?) and if it can be simplified, because I know that in JS there are some useful shorthand coding techniques like:
a || ''
if(a)
if(a.length)
if(a == null)
I've tried to use them here but it only leads to frustration because there is always an edge case which is not covered. Any help appreciated.
You could use exclusive OR and check the values with
if (!oldValue && newValue || oldValue && !newValue) {
// update
}
that means, if either oldValue
is truthy and newValue
is falsy or oldValue
is falsy and newValue
is truthy then make an update of the data.
An extended check for same type and changes.
if (!oldValue && newValue || oldValue && !newValue || typeof oldValue === typeof newValue && oldValue !== newValue) {
// update
}