How to update $Scope.items after push run?

Asked

Viewed 545 times

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>
  • Utilize $scope.$apply() after the push.

2 answers

1

$scope.addItem = function () {
    $scope.items.push({
        nome: $scope.user.nome,
        email: $scope.user.email,
        soma: sum++
    });

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

You don’t need to pass the direct argument in the attribute: ng-click="addItem(user)" the data can be recovered by $scope.

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


Error you are reading in your code:

Typeerror: Cannot set Property 'name' of Undefined

1


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

I created the function updateItem, that takes as argument the update and the respective item to be modified. It goes through the $scope.items and checks which of the items in the array will be updated, when checking it applies 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’s a variable in the scope, called update which contains the update and will be passed in function updateItems:

<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 function updateItem is in the ng-click button Atualizar.

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>
<div ng-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>

  • Thank you @samirbraga, that’s what I needed! However, how do I update multiple items, without the code getting huge and full of conditional?

  • @luccasrodrigo, I imagine that this way it is already possible to update several items, is having problems?

  • we can go to chat?

  • @luccasrodrigo, we can

  • Chat http://chat.stackexchange.com/rooms/51050/comoractualizr-scopitems-apos-execucao-de-push

Browser other questions tagged

You are not signed in. Login or sign up in order to post.