How to update $ scope.items after push execution?

3

JavaScript:

var app = angular.module('app', []);
    app.controller('controlador', function($scope, $http) {
    $scope.user = {};
    $scope.items = [];
    var sum = 1;
    $scope.submitForm = function() {

        $http({
          method  : 'POST',
          url     : 'clone.php',
          data    : $scope.items,
          headers : {'Content-Type': 'application/x-www-form-urlencoded'} 
         })
          .success(function(data) {
            if (data.errors) {
              $scope.erroNome = data.errors.nome;
              $scope.erroEmail = data.errors.email;
            } else {
              $scope.mensagem = data.mensagem;
            }
          });
    };

    $scope.addItem = function (user){
            $scope.items.push({
                nome: $("input[name='nome']").val(),
                email: $("input[name='email']").val(),
                soma: sum++
            });
          user.nome = '';
          user.email = '';  
    };
});

HTML:

<body ng-app="app" ng-controller="controlador">

<form ng-submit="submitForm()">
    <label>Nome: </label><input type="text" name="nome" ng-model="user.nome">
    <span ng-show="erroNome">{{erroNome}}</span>
    <label>E-mail: </label><input type="text" name="email" ng-model="user.email">
    <span ng-show="erroEmail">{{erroEmail}}</span>
    <input type="button" value="Adicionar" ng-click="addItem(user)" />
    <input type="submit" value="Enviar" /><br /><br />

</form>
<br />

<div ng-repeat="item in items">
ID: {{item.soma}}<br />
Nome: {{item.nome}}<br /><label>Novo nome: </label><input type="text" name="nome"><br />
E-mail: {{item.email}}<br /><label>Novo e-mail: <input type="text" name="email"><br /><br />
<input type="button" value="Atualizar" />
<hr />
</div>

</body>
    
asked by anonymous 01.01.2017 / 20:55

2 answers

1

I believe your function is for the button, "Update", so here's a suggestion:

I created the function updateItem , which receives as an argument the update and the respective item to be modified. It walks through $scope.items and checks which of the items in the array is going to be updated, checking to apply only the required update (or name, or email, or both):

  $scope.updateItem = function(update, old) {
    $scope.items.forEach(function(item, i){
      if(item.nome == old.nome && item.email == old.email){
        if(update.nome) item.nome = update.nome
        if(update.email) item.email = update.email
      }
    });
    item.nome = '';
    item.email = '';
  };

And I modified your HTML as follows:

Now there is a variable in the scope, called update that contains the update and will be passed in the updateItems function:

<div ng-repeat="item in items">
    ID: {{item.soma}}
    <br /> Nome: {{item.nome}}
    <br />
    <label>Novo nome: </label>
    <input type="text" name="nome" ng-model="update.nome">
    <br /> E-mail: {{item.email}}
    <br />
    <label>Novo e-mail:
      <input type="text" name="email" ng-model="update.email"> </label>
    <br />
    <br />
    <input type="button" value="Atualizar" ng-click="updateItem(update, item)" />
    <hr />
</div>

The updateItem function is in ng-click of the Atualizar button.

DEMO

var app = angular.module('app', []);
app.controller('MyCtrl', function($scope, $http) {
  $scope.user = {};
  $scope.items = [];
  var sum = 1;

  $scope.addItem = function(user) {
    $scope.items.push({
      nome: user.nome,
      email: user.email,
      soma: sum++
    });
    user.nome = '';
    user.email = '';
  };
  $scope.updateItem = function(update, old) {
    $scope.items.forEach(function(item, i) {
      if (item.nome == old.nome && item.email == old.email) {
        if (update.nome) item.nome = update.nome
        if (update.email) item.email = update.email
      }
    });
    update.nome = '';
    update.email = '';
  };
});
div {
  margin: 10px;
  padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script><divng-app="app" ng-controller="MyCtrl">
  <form ng-submit="submitForm()">
    <label>Nome: </label>
    <input type="text" name="nome" ng-model="user.nome">
    <br>
    <span ng-show="erroNome">{{erroNome}}</span>
    <label>E-mail: </label>
    <input type="text" name="email" ng-model="user.email">
    <span ng-show="erroEmail">{{erroEmail}}</span>
    <br>
    <input type="button" value="Adicionar" ng-click="addItem(user)" />
    <input type="submit" value="Enviar" />
    <br />
    <br />

  </form>
  <br />

  <div ng-repeat="item in items">
    ID: {{item.soma}}
    <br /> Nome: {{item.nome}}
    <br />
    <label>Novo nome: </label>
    <input type="text" name="nome" ng-model="update.nome">
    <br /> E-mail: {{item.email}}
    <br />
    <label>Novo e-mail:
      <input type="text" name="email" ng-model="update.email"> </label>
    <br />
    <br />
    <input type="button" value="Atualizar" ng-click="updateItem(update, item)" />
    <hr />
  </div>
    
01.01.2017 / 22:08
1
$scope.addItem = function () {
    $scope.items.push({
        nome: $scope.user.nome,
        email: $scope.user.email,
        soma: sum++
    });

    $scope.user.nome = '';
    $scope.user.email = '';  
};

You do not need to pass the argument directly on the attribute: ng-click="addItem(user)" if you can retrieve the data by $scope .

Additionally you are trying to update the data like this: user.nome = "" instead of $scope.user.nome = ""

Error you're experiencing in your code:

  

TypeError: Can not set property 'name' of undefined

    
01.01.2017 / 21:29