Node Token Refresh for Data API call
Hey Guys,
In an attempt to learn JavaScript and Node, I’m looking to created a script used to retrieve dataset details. My first script attempt is used to automate a token refresh. I'd like to use this refreshed token as an object that can be parsed and called into a second request capturing the dataset details I’m looking for.
I’ve successfully connected to DOMO, and made the refresh call. I’ve confirmed the script works by console logging the value within Node. The problem I’m having is capturing the response in an Object, Array, or Variable, to parse and push to the Dataset request. Researching, I found due to the asynchronous nature of JavaScript and Node, a promise or callback must be used to capture the results. I’ve decided to take the promise approach and I’m happy with the code yet no matter what I research, I cannot find a way to capture the response “access_token” in any type of object.
My understanding is that as the code executes the variable assignment moves to the top of the execution stack and is assigned prior to the promise completion based on Nodes single thread approach.
Basic understanding: (this is just my currect understanding, I can be 100% incorrect)
The code is called and executed top to bottom, left to right. As the steps complete the stack receives them in order and executes one by one. When the https function is called into the stack, it’s moved to the API or deferred queue and the next step is evaluated. Once the variable assignment is executed the promise is identified and the value set to promise pending. Once all the steps complete and the promise is satisfied, it’s returned to the stack by the event loop for completion. Since the variable assignment has already been set to pending it’s not refreshed with the actual value.
Questions:
- Is JavaScript and Node the best tools for the job?
- Is calling for a refresh token and using the return value to create a new options object something that’s doable? Seems I can’t find any documentation online (Github, Stack overflow etc..) I’ve asked the question on a few developer forums and internally with our web developers yet no one has been able to help me.
- If Node and JavaScript are not suitable, should I be using something like Java or Pythont?
- If suitable, can someone please share their code?
Below is a the basic approach I’m using to accomplish the task. This is just the call used to capture the refresh token that will later be used to call the dataset desired. I can console.log the value and everything checks out, I’m just unable to assign the value to a reusable object.
My code:
//Begin Code
var http = require("https");
var async = require("async");
var tokenOptions = {
"method": "GET",
"hostname": "api.domo.com",
"port": null,
"path": "/oauth/token?grant_type=client_credentials&scope=data%20user",
"headers": {
"Accept":"application/json",
"Authorization": "My request token goes here"
}
};
let NewToken = new Promise( function(resolve,reject) {
//I will change this to a status evaluation, just wanted to force a true value for discovery.
if(1===1){
req = http.request(tokenOptions,async function (res) {
var chunks = [];
var RequestToken = {};
res.on("data", function (chunk) {
chunks.push(chunk);
//console.log(chunks)
})
res.on("end",async function doSomething(res) {
body = Buffer.concat(chunks);
RequestToken = await JSON.parse(body.toString());
resolve(RequestToken.access_token);
// console.log(RequestToken.access_token)
})
})
req.end();
}else{
reject(err);
req.end();
}
});
//Used to console.log the resolved value of the request promise.
NewToken.then(function(){
console.log(NewToken)
})
//End Code
Thank you for the help, I’ve been researching this for weeks and not able to overcome this issue. I'm thinking my understanding or approach is not correct.
Neil Black
Assc Dir Mktg, Optum Corporate
Comments
-
Figure I'd reply with a working script.
I was able to call the token refresh and capture the value using a promise. Once the promise is fullfilled the refresh token is passed to a the datset list request. The better approach would be to chain the promise however using Google Dev tools, It helped to walk through the steps and see the values pass between functions.
Anyways hope this helps anyone faced with a simular issue,
Neil
//Begin Code
//Include the HTTP module
//To install use the following command within the Node command prompt
// npm install http -g
var http = require("https");//Token options used in the HTTP request.
var tokenOptions = {
"method": "GET",
"hostname": "api.domo.com",
"port": null,
"path": "/oauth/token?grant_type=client_credentials&scope=data%20user",
"headers": {
"Accept":"application/json",
//The below access token can be obtained by navigating to the following URL and entering your
//Client ID and Secret, the resulting access token can be entered below, the "Basic" needs to stay
//prior to the actual token key.
// "Basic + Token"
//URL: https://developer.domo.com/explorer#!/auth
"Authorization": "Basic YourTokenGoesHere"
}
};//Create a promise to handle the async HTTP request.
//This request uses the above token to request a updated token used to request the dataset listing.
//The tokens expire so a new request token must be requested.
var newRequest = new Promise(function(resolve,reject){
//1=1 is a defult placeholder that always results in true. I'll add some option handeling
if(1===1){
//submit the actual request
req = http.request(tokenOptions,function (res,error) {
var chunks = [];
var RequestToken = {};res.on("data", function (chunk) {
chunks.push(chunk);
})res.on("end",function (res) {
body = Buffer.concat(chunks);
RequestToken = JSON.parse(body.toString());
resolve (RequestToken);
})
})
//I'd like to capture errors here however, I believe the res.on('error') might be better
//testing the catch using an incorrect URL doesnt invoke the error.
}else{
console.log("An error occured requesting the refresh token:" + err); }
req.end();
});//call the promise forcing the process to wait for the updated token
var RequestResults = function(){
newRequest
.then(function (resolve){
//update the token options for the datset request.
//URL is updates and the new token is provided
tokenOptions.path = '/v1/datasets';
tokenOptions.headers.Authorization = 'bearer ' + resolve.access_token
//************************Adding new promise to handle dataset request**************
var DatasetRequest = new Promise(function(resolve,reject){
if(1===1){req = http.request(tokenOptions,function (res,error) {
var chunks = [];
var RequestToken = {};res.on("data", function (chunk) {
chunks.push(chunk);
})res.on("end",function (res) {
body = Buffer.concat(chunks);
RequestToken = JSON.parse(body.toString());
// console.log(tokenOptions);
console.log(RequestToken);
console.log(RequestToken.length)
resolve (RequestToken);
})
})
}else{
console.log("An error occured requesting the refresh token:" + err); }
req.end();
});
})
.catch(function(reject){
console.log("An error was thrown!:" + reject);
})
};
//Call the initial promise so that the Token is avaliable for the second call
RequestResults()0
Categories
- All Categories
- 1.8K Product Ideas
- 1.8K Ideas Exchange
- 1.6K Connect
- 1.2K Connectors
- 300 Workbench
- 6 Cloud Amplifier
- 9 Federated
- 2.9K Transform
- 102 SQL DataFlows
- 626 Datasets
- 2.2K Magic ETL
- 3.9K Visualize
- 2.5K Charting
- 754 Beast Mode
- 61 App Studio
- 41 Variables
- 693 Automate
- 178 Apps
- 456 APIs & Domo Developer
- 49 Workflows
- 10 DomoAI
- 38 Predict
- 16 Jupyter Workspaces
- 22 R & Python Tiles
- 398 Distribute
- 115 Domo Everywhere
- 276 Scheduled Reports
- 7 Software Integrations
- 130 Manage
- 127 Governance & Security
- 8 Domo Community Gallery
- 38 Product Releases
- 11 Domo University
- 5.4K Community Forums
- 40 Getting Started
- 30 Community Member Introductions
- 110 Community Announcements
- 4.8K Archive