2

my problem is that the ng-repeat is not updating automatically the data. When I press add pin in my code, the element is added correctly to the database. If I reload the page the data appear correctly, but not as angular should. For the record, the Update and delete are working correctly.

Thanks in advance

This is my app.js code:

var app = angular.module("app", []);

app.controller("AppCtrl", function ($http) {
var app = this;

$http.get("/api/pin").success(function (data) {
    app.pins = data.objects;
})

app.addPin = function (scope) {
    $http.post("/api/pin", {"title":"new", "image":"http://placekitten.com/200/200/?image=" + app.pins.length})
        .success(function(data) {
            add.pins.push(data);
        })
}

app.deletePin = function (pin) {
    $http.delete("/api/pin/" + pin.id).success(function(response) {
            app.pins.splice(app.pins.indexOf(pin), 1)
        })
}

app.updatePin = function (pin) {
    $http.put("/api/pin/" + pin.id, pin);
}

})

This is my index.html file:

<html>
<head>
<title>Pin Clone</title>
<script src="angular/angular.js"></script>
<script src="angular/angular-resource.js"></script>
<script src="js/app.js"></script>
</head>
<body ng-app="app" ng-controller="AppCtrl as app">

<button ng-click="app.addPin()">Add Pin</button>
<div ng-repeat="pin in app.pins">
<img ng-src="{{ pin.image }}" alt=""/>
<div class="ui">
    <input type="text" ng-model="pin.title"/>
    <button ng-click="app.updatePin(pin)">Update</button>
    <button ng-click="app.deletePin(pin)">Delete</button>
</div>
</div>


</body>
</html>
1
  • Replace every instance of app.pins with app.data.pins and try again (provably you must attribute an empty object to app.data first: app.data = {};). Commented Jul 19, 2014 at 1:53

3 Answers 3

3

First of all, you should really use $scope (Doc) in your controller. You can read more about the differences in this post.

Thus your controller would look like this.

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

    $http.get("/api/pin").success(function (data) {
        $scope.pins = data.objects;
    });

    $scope.addPin = function () {
        ....
    };

    $scope.deletePin = function (pin) {
        ....
    };

    $scope.updatePin = function (pin) {
        ....
    };
}]);

HTML:

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

    <button ng-click="addPin()">Add Pin</button>
    <div ng-repeat="pin in pins">
        <img ng-src="{{ pin.image }}" alt=""/>
        <div class="ui">
            <input type="text" ng-model="pin.title"/>
            <button ng-click="updatePin(pin)">Update</button>
            <button ng-click="deletePin(pin)">Delete</button>
        </div>
    </div>

</body>

Finally, here comes the core part. You should call $apply (Doc) when your models change. You can read more in this blog post.

$http
    .post("/api/pin", {
        title: "new",
        image:
            "http://placekitten.com/200/200/?image="
                + $scope.pins.length
    })
    .success(function(data) {
        $scope.$apply(function() {
            $scope.pins.push(data);
        });
    });

Thus, the full controller code:

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

    $http.get("/api/pin").success(function (data) {
        $scope.pins = data.objects;
    });

    $scope.addPin = function () {
        $http
            .post("/api/pin", {
                title: "new",
                image:
                    "http://placekitten.com/200/200/?image="
                        + $scope.pins.length
            })
            .success(function(data) {
                $scope.$apply(function() {
                    $scope.pins.push(data);
                });
            });
    };

    $scope.deletePin = function (pin) {
        $http
            .delete("/api/pin/" + pin.id)
            .success(function(response) {
                $scope.$apply(function() {
                    $scope.pins.splice(
                        $scope.pins.indexOf(pin), 1
                    );
                });
            });
    };

    $scope.updatePin = function (pin) {
        $http.put("/api/pin/" + pin.id, pin);
    };
}]);
Sign up to request clarification or add additional context in comments.

1 Comment

Shouldn't an $apply be unnecessary inside $http--isn't that the point? you can't call an $apply inside an $apply when a digest is already occurring--you'll receive an error.
1

Cannot agree with Gavin. First, what you're doing is totally fine. Creating instance of controller is a much better practice than using $scope. Second, $apply() is not needed here.

The problem is ng-repeat created a new scope. While pin is updated, app.pins is not. You should do

var app = angular.module("app", []);

app.controller("AppCtrl", function ($http) {
var app = this;

$http.get("/api/pin").success(function (data) {
    app.pins = data.objects;
})

app.addPin = function (scope) {
    $http.post("/api/pin", {"title":"new", "image":"http://placekitten.com/200/200/?image=" + app.pins.length})
        .success(function(data) {
            add.pins.push(data);
        })
}

app.deletePin = function (index) {
    $http.delete("/api/pin/" + app.pins[index].id).success(function(response) {
            app.pins.splice(index, 1)
        })
}

app.updatePin = function (index) {
    $http.put("/api/pin/" + app.pins[index].id, app.pins[index]);
}

})

and

<html>
<head>
<title>Pin Clone</title>
<script src="angular/angular.js"></script>
<script src="angular/angular-resource.js"></script>
<script src="js/app.js"></script>
</head>
<body ng-app="app" ng-controller="AppCtrl as app">

<button ng-click="app.addPin()">Add Pin</button>
<div ng-repeat="pin in app.pins track by $index">
<img ng-src="{{ pin.image }}" alt=""/>
<div class="ui">
    <input type="text" ng-model="pin.title"/>
    <button ng-click="app.updatePin($index)">Update</button>
    <button ng-click="app.deletePin($index)">Delete</button>
</div>
</div>


</body>
</html>

check here: How to update ng-model on event click using $event in Angularjs

Comments

0

in posted code you've got typo error

app.addPin = function (scope) {
    $http.post("/api/pin", {"title":"new", "image":"http://placekitten.com/200/200/?image=" + app.pins.length})
        .success(function(data) {
           // add.pins.push(data); <--- app not add 
              app.pins.push(data)
        })
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.