sztal sztal - 2 months ago 20
AngularJS Question

AngularJS: POST changes to the server using $resource

I am struggling with the following AngularJS problem.

I have a model in a .json file on the server:

{
feedback: []
}


My aim is to push user-generated data from a form to the feedback array, so every feedback comment is represented as a javascript object.

I tried to use a service that returns an angular $resource pointing to the feedback array in my .json. It is implemented as follows (baseURL just points to a port on localhost):

.service('feedbackFactory', ['$resource', 'baseURL', function($resource, baseURL) {

this.getFeedback = function() {

return $resource(baseURL + 'feedback', null, {'update': {method: 'PUT'}});

};

}])


And then I use a controller to handle the resource object in the following way(
$scope.feedback
is an object storing data generated by a user via a form):

.controller('FeedbackController', ['$scope', 'feedbackFactory', function($scope, feedbackFactory) {

$scope.sendFeedback = function() {

if ($scope.feedback.agree && ($scope.feedback.mychannel === "")) {
$scope.invalidChannelSelection = true;
console.log('incorrect');
}
else {
var feedbackData = feedbackFactory.getFeedback().query(
function(response) {
feedbackData = response;
}
);
feedbackData.push($scope.feedback);
feedbackData.$save();
}
}
}])


Unfortunately I constantly get the following error:
feedbackData.$save is not a function
. According to everything I read so far the feedbackData object should have access to the $save method, but something must be wrong. I spent too many hours on this already, so I will be really thankful for any advice.

EDIT.

After some struggling I tried using
feedback/:id
approach, so I changed the service like this:
.service('feedbackFactory', ['$resource', 'baseURL', function($resource, baseURL) {

this.getFeedback = function() {

return $resource(baseURL + 'feedback/:id', null, {'update': {method: 'PUT'}});

};

}])


And send data to the json on the server like this:

var feedback = feedbackFactory.getFeedback().query(
function(response) {
feedback = response;
$scope.feedback.id = feedback.length;
feedbackFactory.getFeedback().save({id: $scope.feedback.id}, $scope.feedback);
}
);


This time I of course get the error I actually expected - POST can not be done, since the array in the json in an empty array, so I can not address it and any of its non-existing elements by numerical indices. However, I feel that this approach is better anyway and that I am missing on something simple, but important.

Answer

OK, I finally found the solution for my problem that still using the $resource service, so I suppose it means that it conforms to the CRUD constraints (the solution is based on this awesome blog post: https://www.dunebook.com/introduction-to-resource-with-http-service-in-angularjs/#)

So everything is really pretty simple. First I set up my resource via a factory:

.factory('feedbackFactory', ['$resource', 'baseURL', function($resource, baseURL) {

    return $resource(baseURL + 'feedback/:id', null, {'update': {method: 'PUT'}});

}])

Then I just create a new instance of the $resource which I fill with an object containing the feedback info that I take from the $scope in which a user generated it. And then I $save it putting it back to the place where it was originally fetched from ($save handles everything on my behalf):

var newFeedback = new feedbackFactory($scope.feedback);
newFeedback.$save();

Hope it will save someone a few hours of headache.

Comments