node-asana icon indicating copy to clipboard operation
node-asana copied to clipboard

UsersApi.getUsers hides next_page in internal _response

Open barryam3 opened this issue 4 months ago • 2 comments

Based on https://developers.asana.com/reference/getusers UsersApi.getUsers() should support pagination.

I ran the script from the example (with my parameters substituted in):

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = 'REDACTED';

let usersApiInstance = new Asana.UsersApi();
let opts = { 
    'workspace': "REDACTED", 
    'team': "REDACTED", 
    'limit': 1, 
};
usersApiInstance.getUsers(opts).then((result) => {
    console.log('API called successfully. Returned data: ' + JSON.stringify(result.data, null, 2));
}, (error) => {
    console.error(error.response.body);
});

Here's what the documentation says I should get (copied, shortened):

{
  "data": [
    {
      "gid": "60",
      "name": "Justin Rosenstein",
      "resource_type": "user"
    }
  ],
  "next_page": {
    "offset": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJib3JkZXJfcmFuayI6IlsxMDY2MjQ0OTI2NjM2M10iLCJpYXQiOjE3NTkyNjUwMDQsImV4cCI6MTc1OTI2NTkwNH0.sGSTskIjY00kfKT7y2vaWecbZPXwIpJgENbDnISbOjU",
    "path": "/users?team=2415515905262&limit=5&offset=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJib3JkZXJfcmFuayI6IlsxMDY2MjQ0OTI2NjM2M10iLCJpYXQiOjE3NTkyNjUwMDQsImV4cCI6MTc1OTI2NTkwNH0.sGSTskIjY00kfKT7y2vaWecbZPXwIpJgENbDnISbOjU",
    "uri": "https://app.asana.com/api/1.0/users?team=2415515905262&limit=5&offset=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJib3JkZXJfcmFuayI6IlsxMDY2MjQ0OTI2NjM2M10iLCJpYXQiOjE3NTkyNjUwMDQsImV4cCI6MTc1OTI2NTkwNH0.sGSTskIjY00kfKT7y2vaWecbZPXwIpJgENbDnISbOjU"
  }
}

Here's what I actually got:

{
  "data": [
    { "gid": "REDACTED", "name": "Barry McNamara", "resource_type": "user" }
  ],
  "_response": {
    "data": [
      { "gid": "REDACTED", "name": "Barry McNamara", "resource_type": "user" }
    ],
    "next_page": {
      "offset": "REDACTED",
      "path": "REDACTED",
      "uri": "REDACTED"
    }
  },
  "_apiClient": {
    "basePath": "https://app.asana.com/api/1.0",
    "RETURN_COLLECTION": true,
    "authentications": {
      "token": {
        "type": "personalAccessToken",
        "accessToken": "REDACTED"
      }
    },
    "defaultHeaders": {},
    "timeout": 60000,
    "cache": true,
    "enableCookies": false,
    "agent": { "_defaults": [], "jar": {} },
    "requestAgent": null
  },
  "_apiRequestData": {
    "path": "/users",
    "httpMethod": "GET",
    "pathParams": {},
    "queryParams": {
      "workspace": "REDACTED",
      "team": "REDACTED",
      "limit": 1
    },
    "headerParams": {
      "X-Asana-Client-Lib": "version=3.0.16&language=NodeJS&language_version=v24.8.0&os=darwin"
    },
    "formParams": {},
    "bodyParam": null,
    "authNames": ["personalAccessToken"],
    "contentTypes": [],
    "accepts": ["application/json; charset=UTF-8"],
    "returnType": "Blob"
  }
}

So if I want to paginate to get all users for a team I can do it like so but I suppose this might break at any version upgrade:

async function getAllUsersForTeam(team) {
  const users = [];
  let res;
  while (!res || res.next_page) {
    res = await usersApiInstance.getUsers({
      team,
      limit: 100, // max
      offset: res?.next_page?.offset,
    });
    users.push(...res.data);
    // For some reason next_page is only in the internal _response.
    res.next_page = res.next_page ?? res._response?.next_page;
  }
  return users;
}

I can't use https://developers.asana.com/reference/getusersforteam because that is limited to 2000 users. The documentation implies it supports pagination, but if you try to use it on a team with more than 2000 members it just fails and tells you it doesn't support pagination.

I'm on node-asana v3.1.2 which is the most recent. This was done using node v24.8.0

barryam3 avatar Sep 30 '25 21:09 barryam3

@barryam3 I’ve created a Pull Request that implements this fix: https://github.com/Asana/node-asana/pull/304 It exposes next_page at the top level (while preserving backward compatibility). Please review and let me know if I need to adjust anything.

RaoUsama7 avatar Oct 10 '25 22:10 RaoUsama7

@barryam3 is issue got resolved by my solution?

RaoUsama7 avatar Oct 16 '25 23:10 RaoUsama7