When using the ngResource module, my model is not updating properly
I have a little problem with Angular. I am using a module $ngResource
to resolve "comments" from my server:
var app = angular.module('app', ['ngResource']);
app.factory('comment', function($resource) {
return $resource('/comments');
});
app.controller('commentsController', function($scope, comment) {
$scope.comments = comment.query();
});
I am using a directive ngRepeat
to show all comments:
<li ng-repeat="comment in comments">
{{ comment.comment }}
</li>
So far so good.
I want to make it so that when a comment is posted to the server, the property is $scope.comments
updated, updating the view. I've updated commentsController
$scope
to have a: method submitComment
that is called from a directive ngSubmit
:
app.controller('commentsController', function($scope, comment) {
$scope.comments = comment.query();
$scope.submitComment = function() {
var commentToSave = new comment();
angular.copy($scope.comment, commentToSave);
commentToSave.$save(function() {
$scope.comments.push(commentToSave);
});
};
});
When this method is called, the "comment" is successfully posted to the server, but the view is not refreshed as expected. Recall that my directive is ngRepeat
defined on li
. When I post a "comment" a new one is created li
(ie, a new bullet point is created), but the body is empty. What am I doing wrong?
Update: I noticed that if I call $scope.comments.push(commentToSave);
outside of the callback $save
, the view is updated correctly. I think it commentToSave
changes when I call $save
, something like this anyway.
source to share
The $ save function updates the values of the saved item from the response. Therefore, if the answer is empty, the properties commentToSave
will also be empty.
If this is an option for you, you should return the generated value from the backend. This is useful because it is often when you do not have a unique ID when creating an item on a web page. The identifier can then be generated when you insert it into the database. So when you post a new element, you are responding with "created properties", so your controller contains the correct element id. This is especially necessary if you are changing any values and updating the element a second time with $save
.
If you don't want to use the response from the server when doing the save, just copy the values into a new variable and use that when you push an item into the comments array. I'm not sure how you would disable this in the $ resource factory and didn't see any options for it.
source to share
Copy a comment that cannot be changed:
app.controller('commentsController', function($scope, comment) {
$scope.comments = comment.query();
$scope.submitComment = function() {
var commentToSave = new comment(), commentToDisplay = {};
angular.copy(commentToDisplay, commentToSave);
angular.copy($scope.comment, commentToSave);
commentToSave.$save(function() {
$scope.comments.push(commentToDisplay);
});
};
});
source to share