Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access nested objects in json by angularjs $resource

I have .NET WCF service providing REST service. Everything works for me, until I am trying to send object with nested objects. Then I am getting nothing in angularjs. How can I use/access nested object for data exchange?

.NET service part:

[OperationContract] // route prefix 'api'
    [WebGet(UriTemplate = "users/{id}/privileges", ResponseFormat = WebMessageFormat.Json)]
    public PrivilegeSet GetPrivileges(string id)
    {
        var response = new PrivilegeSet();

        List<Role> roles = new List<Role>();
        roles.Add(new Role() { RoleId = 1, Name = "Role 1", Active = true });
        roles.Add(new Role() { RoleId = 2, Name = "Role 2", Active = true });
        roles.Add(new Role() { RoleId = 3, Name = "Role 3", Active = false });
        response.Roles = roles;

        List<SubRole> subRoles = new List<SubRole>();
        subRoles.Add(new SubRole() { SubRoleId = 1, Name = "SubRole 1", RoleId = 1, Active = true });
        subRoles.Add(new SubRole() { SubRoleId = 2, Name = "SubRole 2", RoleId = 1, Active = true });
        subRoles.Add(new SubRole() { SubRoleId = 3, Name = "SubRole 3", RoleId = 1, Active = false });
        response.SubRoles = subRoles;

        return response;
    }

JSON structure:

{
"Roles": [
{
  "Active": true,
  "Name": "Role 1",
  "RoleId": 1
},
{
  "Active": true,
  "Name": "Role 2",
  "RoleId": 2
},
{
  "Active": false,
  "Name": "Role 3",
  "RoleId": 3
}
],
"SubRoles": [
{
  "Active": true,
  "Name": "SubRole 1",
  "RoleId": 1,
  "SubRoleId": 1
},
{
  "Active": true,
  "Name": "SubRole 2",
  "RoleId": 1,
  "SubRoleId": 2
},
{
  "Active": false,
  "Name": "SubRole 3",
  "RoleId": 1,
  "SubRoleId": 3
}
]
}

Angularjs service:

angular.module('privilegeService', ['ngResource']).
    factory('Privilege', function ($resource) {
        return $resource('api/users/:userId/privileges', {userId: '@id'});
    });

Angularjs fetching part:

function PrivilegesCtrl($scope, Privilege) {
    $scope.privileges = Privilege.query({userId:2}); // privileges remains empty using nested objects, with one level object works fine
    ...

Why privileges remains empty when JSON has nested objects? And how to access nested objects in the view?

like image 274
Fanda Avatar asked Feb 20 '13 06:02

Fanda


1 Answers

When you use the $resource service the .query action assumes your response is an array. You can specify that the response is not an array when using .query by specifying it when creating the resource with the third parameter below:

angular.module('privilegeService', ['ngResource']).
    factory('Privilege', function ($resource) {
        return $resource('api/users/:userId/privileges', 
                         {userId: '@id'}, 
                         {'query':  {method:'GET', isArray:false}});
    });

Check out this plnkr for an example. If you take out the {'query': {method:'GET', isArray:false}} your response will be an empty array.

Note 1: your console is likely showing an error TypeError: Object #<Resource> has no method 'push' which, when working with .query, usually means an array is expected from your REST call.

Note 2: the resource action defaults are described in the $resource documentation as follows:

{ 'get':    {method:'GET'},
  'save':   {method:'POST'},
  'query':  {method:'GET', isArray:true},
  'remove': {method:'DELETE'},
  'delete': {method:'DELETE'} };
like image 78
Gloopy Avatar answered Sep 30 '22 19:09

Gloopy