Dev Dev - 1 year ago 62
AngularJS Question

AngularJS Avoid duplicates when updating a CRUD table (normal add to table works)

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 ( === $scope.model.contacts[contact].name.toUpperCase()) {

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:

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).

Answer Source

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) {
  if ( === {
    indexExists = index;
    loop.stop = true;

or With ES6:

var indexExists = $scope.model.contacts.findIndex(function(contact) {
  return ===;       

or even using findIndex method of underscorejs:

_.findIndex($scope.model.contacts, function(contact) { return === 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:

  1. You're passing the old contact to your unique function, you should pass the new contact.



if (isUnqiue(contact, 1)) {


if (isUnqiue($scope.model.selected, 1)) {
  1. You're attributting the $scope.error to the old contact, it should be this:
$scope.errorContact = $scope.model.selected;