I need to iterate values into the URL via for loop an API Query Resource

  • Goal: I want to iterate values into the API's URL. Ex. Url: 'example.com/api/groups//users'.

  • Steps: I tried creating a JS Query to manipulate the url in the API Query Resource but that's not returning anything. I also tried doing it via fetch:

console.log('URL:', url);
console.log('Auth Token:', authToken);

// Make sure `fetch` is available in Retool's custom JS environment
fetch(url, {
  method: 'GET',
  headers: {
    'X-Tableau-Auth': authToken,
  }
})
.then(response => {
  if (!response.ok) {
    throw new Error(`Error fetching data: ${response.status}`);
  }
  return response.text();  // Handle as text (or use .json() if the response is JSON)
})
.then(xmlString => {
  console.log('XML Response:', xmlString);
  // Process the XML response here, if needed
})
.catch(error => {
  console.error('Error:', error);
});
  • Details: I'm not getting any results even with console.log using fetch. I really need to iterate through a list of group ids when calling the API endpoint.

EDIT: Currently going the javascript route to set the URL for the API Query Resource. But I'm getting 'No URL Protocol Specified Error'

Here's my code:

post_TableauCredentials.trigger;
post_TableauSiteID.trigger;
post_Groups.trigger;

//Get Group Data.
//Returns array of IDs from groups data
function getGroupIds() {
  var array_Id = []; //Returns this.

  var array_GroupsData =
    post_Groups.data.parsedXml.tsResponse.groups["0"].group; //Parses xml data from post_Groups resource
  var array_GroupsData_Length = array_GroupsData.length;
  for (var i = 0; i < array_GroupsData_Length; i++) {
    array_Id.push(array_GroupsData[i].$.id);
  }
  return array_Id;
}

//Get user list per group.
//Returns username and ID per group.
function getUserFromGroupId(index, groupId) {
  setValue(groupId);
  get_GroupUsers.url = 'https://*****.tableau.com/api/3.24/sites/*******/groups/'+groupId+'/users?pageSize=1000';
  get_GroupUsers.method = 'GET';
  console.log(get_GroupUsers.url)
  console.log(get_GroupUsers.method)
  get_GroupUsers.trigger();
  return get_GroupUsers.data
}

function main() {
  var array_groupId = getGroupIds();
  var array_groupId_Length = array_groupId.length;
  var temp;
  for (var i = 0; i < 10; i++) {
    temp = getUserFromGroupId(i,array_groupId[i]);
  }

  return temp;
}

return main();

Here's the error:

Hey @lex_0,

I think I get what you’re going for – it sounds like you want to call the Tableau API multiple times. One idea could be to set up a REST API resource that connects to the Tableau API, and use variables in the URL to make it dynamic.

From there, you could update the variable and call the API again, or even create a script that updates the variable and triggers the API resource automatically.

Just some ideas! Let me know what you think, happy to help brainstorm more.

Found the solution. I used 'additionalScope' for queries.

function getUserFromGroupId(index, groupId, groupName) {
   get_GroupUsers.trigger({
    additionalScope: {
      groupID: groupId  // Dynamically set this value
    },
    onSuccess: function(data) {
      
      var usersList = data.parsedXml.tsResponse.users[0].user;
      console.log(groupId + ':' + groupName, usersList);
      return usersList;
    },
    onFailure: function(error) {
      console.log(error)
      console.error('Failed to fetch user data:', error);
    }
  });
}

groupID in additionalScope sets the url dynamically. You must also add {{groupID}} to the URL. It will be highlighted as red but that's okay.

https://*************.tableau.com/api/3.24/sites/*******************/groups/{{groupID}}/users?pageSize=1000

1 Like