Check if object already exists in array by id

1

I'm developing a project, where a user will set up a list of contracts, searching for cpf, but if he searches for the same cpf 2 times, the contract repeats in the list, as I do to check if the contract already exists in the array list and prevent it from being inserted

    $scope.contratos = [];
   $scope.Pesquisar = function(){
   $http.post('php/GetContratosProtocolo.php', {
  'cpf':cpf
   }).success(function(data){
  if(typeof data == 'object'){  
      $scope.contratos.push(data)
  }else{
  showerror('Contrato Não Encontrado')
   }

    }).error(function(data){
  console.log(data)
   })
   }
    
asked by anonymous 28.09.2016 / 17:06

4 answers

2

Every time the user searches for the CPF, a connection with the server will be established, even if it is an already searched CPF and this is unnecessary, since this information can be stored on the client side.

What I suggest in the code below is that the CPF is included as an index of the contratos array, which makes sense because currently each object within the contratos array refers to a CPF and is precisely the duplication you want avoid:

$scope.contratos = [];
$scope.Pesquisar = function(){
   //verifica se o CPF é um índice do array contratos 
   //e só faz um novo request se o CPF ainda não foi pesquisado.
   if(typeof $scope.contratos[cpf] === 'undefined') {
       $http.post('php/GetContratosProtocolo.php', {
          'cpf':cpf
       })
       .success(function(data){
          if(typeof data == 'object'){  
              //adiciona um novo elemento ao array utilizando o CPF como índice.
              $scope.contratos[cpf] = data;
          }else{
              //adiciona na mesma o CPF no array de contratos, embora o resultado seja 'null', não deixa de ser uma resposta válida.
              $scope.contratos[cpf] = null;
              showerror('Contrato Não Encontrado')
          }
       })
       .error(function(data){
           console.log(data)
       })
   }
};

Then to extract the data from the array contratos just make a forEach :

$scope.contratos.forEach(function(value, key) {
     //key = cpf utilizado como índice
     //...
});
    
28.09.2016 / 17:40
1

Luiz, I suggest using the contains method of the array to check if the object already exists in the array before giving push :

$scope.contratos = [];
$scope.Pesquisar = function(){
$http.post('php/GetContratosProtocolo.php', {
  'cpf':cpf
  }).success(function(data){
    if(typeof data == 'object'){  
      if($scope.contratos.contains(data))
      {
        showerror('Contrato Já Registrado')
      }else{
        $scope.contratos.push(data)
      }
    }else{
      showerror('Contrato Não Encontrado')
    }
  }).error(function(data){
    console.log(data)
  })
}

Font: link

Edit: I'm sorry, this feature is still in experiment and does not exist natively. To work, you must run before:

if (![].contains) {
  Object.defineProperty(Array.prototype, 'contains', {
    enumerable: false,
    configurable: true,
    writable: true,
    value: function(searchElement/*, fromIndex*/) {
      if (this === undefined || this === null) {
        throw new TypeError('Cannot convert this value to object');
      }
      var O = Object(this);
      var len = parseInt(O.length) || 0;
      if (len === 0) { return false; }
      var n = parseInt(arguments[1]) || 0;
      if (n >= len) { return false; }
      var k;
      if (n >= 0) {
        k = n;
      } else {
        k = len + n;
        if (k < 0) k = 0;
      }
      while (k < len) {
        var currentElement = O[k];
        if (searchElement === currentElement ||
            searchElement !== searchElement && currentElement !== currentElement
        ) {
          return true;
        }
        k++;
      }
      return false;
    }
  });
}
    
28.09.2016 / 17:51
0

A simple way with few changes would be to create a new function to check if the array already has the value and call it in a condition before adding:

function contains(array,value)
{
    var doescontain = false;
    array.forEach(function(element){
        if(element == value)
        {
            doescontain = true;
        }
    },this);
    return doescontain;
}

Putting it into your condition would look like this:

if(typeof data == 'object'){  
  if(contains($scope.contratos,data))
  {
    showerror('Contrato Já Registrado')
  }else{
     $scope.contratos.push(data)
  }
}else{
   showerror('Contrato Não Encontrado')
}
    
28.09.2016 / 19:48
0

I was able to solve it as follows

      if(typeof data == 'object'){

    for(var i=0; i<data.length; i++){
      var objExiste = $.grep($scope.contratos, function(n, x){
                    return n.idcontrato == data[i].idcontrato;
                  })

                  if(objExiste.length == 0){
                     $scope.contratos.push(data[i])
                   } else {
          console.log('contrato ja inserido')
      }

        }


}else{
  showerror('Contrato Não Encontrado')
}
    
28.09.2016 / 20:19