6

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?

2
  • Have you checked in any dev tools like Firebug or Chrome Inspector for what the server is returning? Commented Feb 20, 2013 at 7:18
  • Of course, it is the JSON structure part. It it is the server response. Commented Feb 20, 2013 at 7:42

1 Answer 1

8

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'} };
Sign up to request clarification or add additional context in comments.

7 Comments

It works, thank you. How can I now access nested arrays in the view?
The resource returns an object with two arrays in it called Roles and SubRoles. You can reference them using privileges.Roles and privileges.SubRoles respectively. I updated the plnkr with an example.
I was trying it by this way, but it needs deeper browser refresh after changes. Thank you very much for your help.
@Gloopy Why can't i go privileger.Roles[0].$delete when isArray:false is there anyway that is achievable
@Deeptechtons you can convert it to the resource using new Resource(obj) where Resource is your $resource (like Role or SubRole). See line 27 in the $resource documentation for an example.
|

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.