Reputation: 149
I am trying to create a simple CRUD table that does not allow duplicate names. I have been able to get the duplicate to work when adding a contact to the table, but it does not seem to be working when updating the table.
Below is my simple function that verified uniqueness of a contact:
// (allowed) dupCount is 0 when adding, and 1 when in update
// mode to allow saving the contact without making any changed.
var isUnqiue = function(newContact, dupCount) {
var returnVal = true;
var count = 0;
for (var contact in $scope.model.contacts) {
if (newContact.name.toUpperCase() === $scope.model.contacts[contact].name.toUpperCase()) {
count++;
}
}
if (count > dupCount) {
returnVal = false;
}
return returnVal;
}
For some reason, it the duplicate in update mode is not working at all! Even if I update 3 or 4 contacts to the same name, the 'if (count > dupCount) ... ' statement always seem to compare 1 and 1.
Here is a JSFiddle with the entire code: https://jsfiddle.net/7ay9nsLv/
Simple scenario:
Add 'Adam, Smith'
1. Edit 'Adam, Smith', Save without Changing > Good
2. Add 'Adam, Smith' again > Duplicate Error
Add 'Adam, SmithX'
3. Edit 'Adam, SmithX' to 'Adam, Smith' > Duplicate Error
Also note, that the data in the table could be sorted and all, so not sure if passing $index to the controller would be too useful (unless sorting doesn't change the data index).
Upvotes: 0
Views: 563
Reputation: 24894
First you're doing something redudant in your for-loop
, you can simply use the Array.prototype.forEach() method to find if the index exists:
// Use named function to stop looping correctly
var indexExists = -1;
$scope.model.contacts.forEach(function loop(contact, index) {
if (loop.stop) {
return;
}
if (contact.name.toUpperCase() === newContact.name.toUpperCase()) {
indexExists = index;
loop.stop = true;
}
});
or With ES6:
var indexExists = $scope.model.contacts.findIndex(function(contact) {
return contact.name.toUpperCase() === newContact.name.toUpperCase();
});
or even using findIndex method of underscorejs:
_.findIndex($scope.model.contacts, function(contact) { return contact.name.toUpperCase() === newName });
Then simply check:
return indexExists == -1 && indexExists !== idx || indexExists === idx && $scope.model.contacts[indexExists].name.toUpperCase() === newName;
It will returns true only if the user doesn't exists or if it exists and it's editing itself.
Now, let's go to the error:
You've commited 2 mistakes:
unique
function, you should pass the new contact. Change
this:
if (isUnqiue(contact, 1)) {
for:
if (isUnqiue($scope.model.selected, 1)) {
$scope.error
to the old contact, it should be this:$scope.errorContact = $scope.model.selected;
Upvotes: 1
Reputation: 295
You should catch duplicate error not on client, but on server)) Create Uniq constraint (or primary key if it doesn't exists) on UserName field. So when you trying put or post duplicate, db throws error. You can catch it and redirect on some error page, or add something error info to response, or just show backend error.
Upvotes: 0