Brayan Serrano
Brayan Serrano

Reputation: 5

Update model in ng-repeat when is self-updated

I've got an array in my scope and I am iterating over each element with an input in the html template:

Controller:

    app.controller("otherArticleCtrl", ["$scope", "$http", function($scope, $http) {

        $scope.articles = [{ url: 'index.php', title: "First"}, { url: 'index.php', title: "Second"}];
    }]);

Template:

<div ng-repeat="(key, article) in articles track by $index">
  <h1>{{ article.title }}</h1>
  <input type="text" ng-model="article.url"/>
</div>

I need when user modifies the url in the input, make an AJAX get call, and update the article title.

I've made a watch function looping through the array:

for(var i=0; i < $scope.articles.length; i++) {
    $scope.$watch('articles['+i+'].url', function(new, old){
       if(new != old){
           $http({
               method: 'GET',
               url: new
           }).then(function successCallback(response) {
               $scope.articles[i].title = response.title;
           });
       }
    }, true);
}

But $scope.articles[i] is undefined and I don't know how to get the reference of the model or element that is changed.

Any ideas? Thanks for help.

Upvotes: 0

Views: 863

Answers (2)

Shaishab Roy
Shaishab Roy

Reputation: 16805

Should not use $watch in any loop. In this case you can use ng-change instead of $watch. and send index number in ng-change function. like ng-change="changeUrl($index)". and function shown in bellow.

can try:

In html:

<div ng-repeat="(key, article) in articles track by $index">
  <h1>{{ article.title }}</h1>
  <input type="text" ng-model="article.url" ng-change="changeUrl($index)"/>
</div>{{index}}

In controller:

$scope.articles = [{ url: 'index.php', title: "First"}, { url: 'index.php', title: "Second"}];

  $scope.changeUrl =  function(index){
  $http({
            method: 'GET',
            url: $scope.articles[index].url
        }).then(function successCallback(response) {
            $scope.articles[index].title = response.title;
        });
  };

you can use $http.get

$http.get($scope.articles[index].url)
    .then(function(response) {
        $scope.articles[index].title = response.title;
    });

Upvotes: 1

Zonedark
Zonedark

Reputation: 249

I'd suggest using ngChange instead.

You can do something like this :

<input type="text" ng-model="article.url" ng-change="somethingChanged()"/>

And add the function inside your controller. If you need to know the index of the element that changed you can use $index from the ng-repeat to know where is the data that changed :

    <input type="text" ng-model="article.url" ng-change="somethingChanged($index)"/>

$scope.somethingChanged = function(index) {
   $scope.articles[index];   <--------- Here is the element that changed
}

Happy coding!

Upvotes: 0

Related Questions