0

I've read answers to similar questions here but none seem to correct the problem I'm seeing. Given:

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

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

postAPI.factory("Post", ["$resource", 
    function postFactory(resource) {
        return resource("/post");
    }
]);

postAPI.controller("PostIndexCtrl", ["$scope", "Post",
    function($scope, Post) {
        Post.query(function(data) {
            $scope.response = data;
        });
    }
]);

postAPI.controller("CreateCtrl", ["$scope", "Post",
    function($scope, Post) {
        Post.save({
            title: "Title",
            body: "Body",
            tags: ["one", "two", "three"],
        });
    }
]);

Error received (docs): "Error in resource configuration for action save. Expected response to contain an object but got an array".

Which would be fine, except that as far as I can see my backend does return a single object. Tested with curl:

curl -H "Content-Type: application/json" -X POST -d '{"title":"foo","body":"bar","tags":["wombat"]}' http://localhost:8080/post/

Response:

{"title":"foo","body":"bar","tags":["wombat"],"created":"...","modified":"...","id":12345}

(edits for brevity, same format). The PostIndexCtrl works as expected, returning an array of post objects. Any clues as to why CreateCtrl might be seeing an array when curl works fine?

2 Answers 2

1

use isArray: false

isArray – {boolean=} If true then the returned object for this action is an array

return $resource("/post", {}, {
  'query': {
    method: 'GET',
    isArray: false
  },
  'get': {
    method: 'GET',
    isArray: true
  }
});

Sign up to request clarification or add additional context in comments.

1 Comment

I really appreciate you taking the time to respond. In fact, I believe isArray defaults to false for $resource.save (only $resource.query has isArray: true) but it was a good thought and I was led to re-examine my backend code, which led to a fix. Thanks!
1

Well, this was my own silly fault as usual. However the error was a bit 'interesting' to interpret, so in case anyone strikes the same thing here's a summary.

My API was returning different responses for the path /post/ than /post. /post/ functions as expected, and that's what I was checking with curl. However when I removed the trailing slash in the curl syntax I got back:

<html>
    <head>
        <title>404 Not Found</title>
    </head>
<body>
...

etc. From what I can gather, angular attempts to serialise this and ends up with an array, hence the error. My fault for not testing the backend thoroughly enough, although in my defence it works fine for GET requests (both /post/ and /post return JSON). Because of this, I'd taken the trailing slash away since I noticed Angular was stripping it.

Anyway, hopefully this helps out someone stuck in the same hole. The fix is at the top of the API: $resource docs:

app.config(['$resourceProvider', function($resourceProvider) {
    // Don't strip trailing slashes from calculated URLs
    $resourceProvider.defaults.stripTrailingSlashes = false;
}]);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.