Make angularjs $resource return array of [OO] objects
Asked Answered
J

2

5

How to make angularjs $resource return an array of objects derived/prototyped from specified domain object?

Here is an example on http://plnkr.co/edit/AVLQItPIfoLwsgDzoBdK?p=preview that processes a set of Notes objects.

app.controller('MainCtrl', function($scope, NoteResource) {
$scope.name = 'World';
$scope.notes  = NoteResource.query();

$scope.spellCheckAllNotes = function() {
  angular.forEach($scope.notes, function(note) {
    note.spellCheck();
   });
 }
});

The issue is that $resource returns array of Resources and not an array of Notes with Resource methods added to prototypes.

[solution shall follow "good" javascript practices]

Jinnah answered 7/5, 2014 at 16:30 Comment(1)
A follow up: stackoverflow.com/questions/23528451Jinnah
M
10

Here is the completed plunker. Yes raw json is parsed to JSON object. It is using transformResponse as mentioned by Armando.

app.factory('NoteResource', ['$resource',
  function($resource) {
    var res =  $resource('http://okigan.apiary.io/notes/:id', {}, {
      query: {
        method: 'GET',
        params: {
        },
        isArray: true,
        transformResponse: function(data, header){
          //Getting string data in response
          var jsonData = JSON.parse(data); //or angular.fromJson(data)
          var notes = [];

          angular.forEach(jsonData, function(item){
            var note = new Note();
            note.noteTitle = item.title;  
            notes.push(note);
          });

          return notes;
        }
      }
    });
    return res;
  }
]);

Just to show title is not used from the raw resource, I modified title to noteTitle in Note and in html.

Marvismarwin answered 7/5, 2014 at 17:47 Comment(8)
for the JSON parsing, you can stick with the Angular framework by using var jsonData = angular.fromJson(data);Sartor
Yes definitely an option, updated accordingly, thanks. @SartorMarvismarwin
btw, I used angular.extend() which automates the process even moreJinnah
Does this still work with later AngularJS versions. For me it's still a series of Resource objects and a couple of others like $promise and resolve.Elberfeld
Yes it does. I am using the same principle in v1.3.13 @ElberfeldMarvismarwin
The notes object for me inside the transformResponse is an array of objects as we'd want, but it's almost like the value is not getting returned. Outside of it, it is still the same series of resource objects and $promise and resolve. Any indication to what could be going wrong?Elberfeld
I created a new plnk for it: plnkr.co/edit/9ZG7sLe7ZpQXKkNbZbSI. I'm still seeing the old behavior. Maybe I should raise a separate question.Elberfeld
it's not that much good, once the service returns, it will change objects type to resource, not note... i have same issue... it introduce bugs with ts interface and object types...Reserpine
D
1

You can manipulate your data using transformResponse option in your resource service definition (make sure to set isArray to true):

angular.module('services', ['ngResource']).
    factory("yourService", function ($resource) {
        return $resource(
            '/custom/url', {}, {
            get: {
                method: 'GET',
                isArray: true,
                transformResponse: function(data, headers){
                    //
                    // transform to array of objects 
                    return data;
                }
            }
        }
    );
});
Dimenhydrinate answered 7/5, 2014 at 17:34 Comment(2)
data seems to be raw json, not objects -- please complete the solution (in plunker the button will show message box)Jinnah
In the comments it says: "transform to array of objects" you need to add your own logic.Dimenhydrinate

© 2022 - 2024 — McMap. All rights reserved.