0

I want to create a Custom Action on Resource, which will process the results received from the server.

angular.module('problem', ['ngRoute', 'ngResource'])
    .factory('Abc', function ($resource) {
      return $resource('api/abc/:abcId', {abcId: '@id'}, {
            customQuery: {
              method: "GET",
              isArray: true,
              interceptor: {
                response: function (response) {
                  // some operations that manipulate data based od response
                  response.data = [5, 6]; // for simplifity
                  console.log("manipulation finished"); // log is saved
                  return response;
                }
              }
            }
          }
      );
    })
;

But when I use the Custom Action, I get the unmodified results instead of processed. Here is the code showing the expected behavior (and in comments relevant errors):

describe('Abc', function () {
  beforeEach(module('problem'));
  var $httpBackend;
  beforeEach(function () {
    angular.mock.inject(function ($injector) {
      $httpBackend = $injector.get('$httpBackend');
    })
  });

  it('should return converted array when customQuery called', inject(function (Abc) {
    $httpBackend
        .expectGET('api/abc')
        .respond([
          {id: 'uid1', name: 'name1'},
          {id: 'uid2', name: 'name2'},
          {id: 'uid3', name: 'name3'},
          {id: 'uid4', name: 'name4'}
        ]);

    var result = Abc.customQuery();
    $httpBackend.flush();

    expect(result.length).toBe(2); // fails with "Expected 4 to be 2."
    expect(result[0]).toBe(5);     // fails with "Expected { id : 'uid1', name : 'name1' } to be 5."
    expect(result[1]).toBe(6);     // fails with "Expected { id : 'uid2', name : 'name2' } to be 6."

  }));
});
1
  • The problem is currently out of date, but I think I should have returned a new response object with new data instead of tampering it. Propably response.data is immutable or even frozen. Commented Jul 15, 2018 at 23:10

2 Answers 2

1

Maybe what you need is to add a new transformResponse transformation, you can easily do that like this (remember to inject $http):

transformResponse: $http.defaults.transformResponse.concat([
    function (data, headersGetter) {
       return data.objects
    }

Difference is, result will be substituted by response.resource, while the return value of the interceptor is the value that is resolving result.$promise

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

Comments

0

thank you for the "interceptor" idea!

in my opinion

response.data = [5, 6]; // for simplifity
return response;

should return a response-object, with a property-array "data", so

result.length;

should fail.

For manipulating the results of a resource response better use response.resource instead of response.data - there are the real REST objects (with CRUD methods)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.