javascriptangularjsangularjs-resource

How do I get a null response from a $resource?


How do I get a null response from a $resource?

I am running this:

angular.module("services").factory('Member', function($resource) {
  var Member = $resource('/api/v1/member.json');

  Member.current = Member.get();

  return Member;
});

But the server is responding with:

null

Because the user is not logged in.

But when I log the result I get this:

Resource
  0: "n"
  1: "u"
  2: "l"
  3: "l"
  $promise: Object
  $resolved: true
  __proto__: Resource

Where as I would have expected literally null.


Solution

  • $resource.get method, by default, expects the JSON response to be an object (when parsed). When calling $resource.get(), the result is going to be an instance of the $resource.

    In your example, calling Member.get({id:1}) will produce a $resource instance that is created by calling new Member() source and then populated source (when XHR is completed) with properties of the parsed JSON response:

    shallowClearAndCopy(data, value);
    

    The signature of the function with which your Member instance is populated is as follows:

    function shallowClearAndCopy(src, dst) {
      dst = dst || {};
    
      angular.forEach(dst, function(value, key){
        delete dst[key];
      });
    
      for (var key in src) {
        if (src.hasOwnProperty(key) && key.charAt(0) !== '$' && key.charAt(1) !== '$') {
          dst[key] = src[key];
        }
      }
    
      return dst;
    }
    

    Glancing the function body you will realise that the function does not expect src parameter to be anything else but object (for (var key in src) { ...). So, if you provide it with string "null" the result will be:

    {1: "n", 2: "u", 3: "l", ...}
    

    ngResource is built to support a RESTfull API with JSON as an implied data transfer format, hence you won't be able to use responses such as "null" or anything else which isn't a valid JSON.


    Unless.

    Unless you make use of transformResponse to convert "null" to something like {'null': true} on the fly:

    app.factory('Member', function($resource) {
      var Member = $resource('member.txt', {}, {
        get: {
          method: 'GET',
          isArray: false,
          transformResponse: function(data, headersGetter){
            if(data === 'null'){
              return {null: true};
            }
            return angular.fromJson(data);
          }
        }
      });
      return Member;
    });
    
    $scope.member = Member.get({id: 1});
    console.log($scope.member); // --> {null: true}
    

    DEMO