Search code examples
javascriptangularjsangular-resource

angular resource error when objects are returned


Im using angular's resource to query some data, the problem is that what the query returns is not this:

[
    {"id":"5-w2k93ylznp6tj4i"}
    {"id":"6-njzmmwcpkw23ayvi"}
]

its this:

{"id":"5-w2k93ylznp6tj4i"}
{"id":"6-njzmmwcpkw23ayvi"}

instead of getting an array of objects, i get several objects, this makes angular throw this error:

SyntaxError: Unexpected token {
at Object.parse (native)

I think the error is because it does not expect another object. That query is for two items, if i query for just 1 item i get just one object and no error. I suspect that when there are two items, it does not expect a second object and throws the error in the first curly bracket after the first object ends.

Some code:

This is the resource:

list: resource (
            '/api/products',
            {
                limit: '@limit',
                skip: '@skip',
                sort: '@sort'
            }, 
            {
                query: {
                    method: 'GET',
                    interceptor: {
                        response: function (data) {
                            console.log('response in interceptor', data);
                        },
                        responseError: function (data) {
                            console.log('error in interceptor', data);
                        }
                    },
                    isArray: false
                }
            }
        ) 

Where the resource is used:

 factory.loadProducts = function(skip, sort){
    var data = Api.Product.list.query(
        {
            limit: appDataVars.limit,
            skip: skip,
            sort: sort
        }, function(response)
        {
            appDataVars.productsList = response;
        }, function(error)
        {
            console.error(error);
        });

    return data.$promise;
};

It always hits the error callback.

My problem is that i cant modify the api, i have to find a way to handle that result set in angular. Any idea how i can achieve that? Thanks.


Solution

  • Set the query object of the resource to contain a property for transformResponse set to the empty array:

    query: {
        method: 'GET',
        interceptor: {
            response: function (data) {
                console.log('response in interceptor', data);
            },
            responseError: function (data) {
                console.log('error in interceptor', data);
            }
        },
        isArray: false,
        transformResponse: []
    }
    

    This will force the response to be treated as a string then change your function that handles the response to be:

    function(response)
    {
        appDataVars.productsList = eval('[' + response.replace(/\n/g, ',') + ']');
    }
    

    If the response string is not separated by a newline between objects change it to be response.replace(/}\s*{/g, '},{') (although this is quite a naive regex).

    It's a bit hacky, but it should be a workaround since you can't modify the API.