Search code examples
angularjsangular-resource

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.


Solution

  • 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.