get value from previous request and pass to another request in nodejs - javascript

I have a scenario where I am trying to get the parsed json response of the variable from the below POST request which I want to store in a variable and pass again to the next GET request in the headers. The approach that I am trying now doesn not give the expected results, Is there anything wrong here how should be my approach here to get the expected results, any help is appreciated.
PS : I am new to nodejs
var request = require('request');
var headers = {
'Accept': 'application/json',
'Accept-Encoding': 'gzip, deflate',
'Authorization': 'Basic Y2Y6',
'Connection': 'keep-alive',
'Content-Length': '95',
'User-Agent': 'python-requests/2.22.0',
'content-type': 'application/x-www-form-urlencoded'
};
var dataString = 'grant_type=password&username=userpp&password=Password';
var options = {
url: 'https://testurl/oauth/token',
method: 'POST',
headers: headers,
body: dataString
};
let ab;
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
//console.log(body);
var parsedBody = JSON.parse(body)
//console.log(parsedBody["access_token"])
ab = parsedBody["access_token"];
}
}
request(options, callback);
var headers1 = {
'Accept': 'application/json',
'content-type': 'application/x-www-form-urlencoded',
'Authorization': `'bearer ' ${ab}`
};
var options1 = {
url: 'https://testurl1.com?getdata=user',
method: 'GET',
headers: headers1
};
function callback1(error1, response1, body1) {
if (!error1 && response1.statusCode == 200) {
console.log(body1);
}
}
request(options1, callback1);

The problem here is that you're running asynchronous code but treating it synchronously
You see, when you call request(options, callback); and then request(options1, callback1); inline like that, by the time the second request runs, the first callback hasn't happened yet
One way to get around this: put the second request INSIDE the first callback function.
Big brain time: use the request-promise library and learn how to make requests using promises and chaining .then() callbacks.
Humungous brain time: learn how to use async/await features as another nicer way to interact with promises

Related

use a specific value from JSON response from GET request via fetch --> to a POST request

the main goal here is to use the part of the response, in the 2nd POST requset.
Let me explain -
given the following endpoint:
https://www.example.com/Applications/?api-version=1&_cacheToken=1675420688869
the response from sending a GET request to the endpoint is :
{"field1":"","Items":[{"Name":"app:\/appname","field2":"appnumber","field3":"appvers","Status":"Ready","Parameters":[],"health":"Ok","kind":"numbers","ids":{"id":[]},"met":{"met1":{}},"Id":"1"}]}
I would like to use only the value of "appname".
hence i'm using it as follows -
---SNIP---
...
.then(data => {
const appname = data.Items[0].Name;
const appname_updated = appname.replace('app:/', '');
...
---SNIP---
I would like to use it with a second fetch request, but this time in a form of POST (in the endpoint itself and in the body):
return fetch('https://www.example.com/deploy/'+appname_updated+'/?api-version=1', {
method: 'POST',
headers: { 'Accept': 'application/json, text/plain, */*', 'Content-Type': 'application/json; charset=utf-8' },
mode: 'no-cors',
body: JSON.stringify({
appname: appname_updated,
field1: "blah"
})
});
})
How this can possible be done ? so the first GET will be sent, receieve 200 ok,
and once it got the 200 status, the POST should send right after with the proper
values populated.
No matter what i've tried so far, nothing seems to be send the second POST rquest.
(I've tried it with asyc/wait etc.)
----- update ----
this is the full code -
<script>
const firstUrl = "https://example.com/Applications/?api-version=1";
const secondUrl = "https://example.com/deploy/";
async function fetchData() {
try {
const response = await fetch(firstUrl, {
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json; charset=utf-8'
}
});
if (response.status === 200) {
const data = await response.json();
const appname_updated = data.Items[0].Id;
const secondResponse = await fetch(secondUrl + appname_updated + '/?api-version=1', {
method: "POST",
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json; charset=utf-8'
},
body: JSON.stringify({
appname: appname_updated,
...rest of JSON
})
});
if (secondResponse.status === 200) {
console.log("POST request successful");
} else {
console.error("Error with POST request");
}
} else {
console.error("Error with GET request");
}
} catch (error) {
console.error("Error with fetch: ", error);
}
}
fetchData();
</script>
Thanks
'no-cors' tells fetch to fail silently if you try to do anything which requires permission from CORS.
Making a cross-origin request with 'Content-Type': 'application/json; charset=utf-8' requires permission from CORS.
Don't use 'no-cors'.

Cascading two scripted API requests togethor

I am trying to check endpoint availability by cascading two api requests and passing first request's response(token) into another in authorization header field. Although the token is getting generated, the second api is not capturing the correct token in the 'token' variable. Let me know scripting error am making. Is there a way to print my authorization field value?
Output of the script is as below:
{
"error": "Invalid token."
}
401
AssertionError [ERR_ASSERTION]: Expected 200 response
Code:
var assert = require('assert');
var request = require('request');
var options2,token,info;
var options = {
'method': 'POST',
'url': '1',
'headers': {
'Content-Type': 'application/x-www-form-urlencoded'
},
form: {
'client_id': '*',
'client_secret': '**',
'grant_type': 'client_credentials'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
info = JSON.parse(response.body);
console.log(info.access_token);
token=info.access_token;
});
var request = require('request');
var options2 = {
'method': 'GET',
'url': '***',
'headers': {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token,
}
};
request(options2, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
console.log(response.statusCode);
assert.ok(response.statusCode == 200, 'Expected 200 response');
});
Move the call
request(options2, function (error, response),
inside the callback function of request 1, along with options2.
Since request 1 call (token one) can take some time your request 2 will be fired while you still haven't received response for token call. You can also use Async/Await to make it more clear, since callbacks makes things hard to read.

Request for JavaScript works, but not for GoogleScreen. What's the difference?

Please, help. I can't find the error and I don't understand why the request is not working. It seems to me that it's just Google's IP blocked by the site I'm making a request to. The same request for JavaScript works.
function pleaseWork() {
var myHeaders = {
'contentType': 'application/json',
'Authorization': 'Bearer 5cd4ac65-f71b-3eaa-93af-78610a7aa320',
}
var raw = ["1111111111111"]
var requestOptions = {
'method': 'POST',
'headers': myHeaders,
'payload': JSON.stringify(raw)
};
result = UrlFetchApp.fetch("https://www.ukrposhta.ua/status-tracking/0.0.1/statuses/last", requestOptions)
Logger.log(result)
}
Working Javascript request:
var myHeaders = new Headers();
myHeaders.append("Authorization", "Bearer 5cd4ac65-f71b-3eaa-93af-78610a7aa320");
myHeaders.append("Content-Type", "application/json");
var raw = JSON.stringify([
"1111111111111"
]);
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
};
fetch("https://www.ukrposhta.ua/status-tracking/0.0.1/statuses/last", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
How to do it right?
In your Google Apps Script, the data is sent as form by default. When I saw your Javascript, it seems that the data is required to be sent as data with application/json. So you'll need to modify the script as follows.
From:
var requestOptions = {
'method': 'POST',
'headers': myHeaders,
'payload': JSON.stringify(raw)
};
To:
var requestOptions = {
'method': 'POST',
'headers': myHeaders,
'payload': JSON.stringify(raw),
'contentType': 'application/json',
};
Reference:
fetch(url, params)
Note:
I think that this modification is the same as the request of your Javascript. But, if an error occurs, please confirm your values of raw and your access token, again.
Added 1:
Your showing script was modified for testing. Please set your access token and the value of raw and test it again.
function modified_pleaseWork() {
var myHeaders = { 'Authorization': 'Bearer ###' };
var raw = ["1111111111111"];
var requestOptions = {
'method': 'POST',
'headers': myHeaders,
'payload': JSON.stringify(raw),
'contentType': 'application/json',
};
var result = UrlFetchApp.fetch("https://www.ukrposhta.ua/status-tracking/0.0.1/statuses/last", requestOptions);
Logger.log(result.getContentText())
}
Added 2:
From your following reply,
but the solution doesn't work for me. I saw you added a modified script. You can also test it with the parameter "Bearer ###" Error 403. But it is not in the JavaScript code. I don't understand what's wrong?
I confirmed the status code 403 from your reply. In this case, it is considered that the site cannot be directly accessed from the Google side. Ref I think that the reason for your issue is due to this.
But, in the case of this situation, there is a workaround. Here, I would like to propose using this workaround. Ref
Sample script:
In this case, the request is run on the custom function. By this, I thought that the status code 403 might be able to be avoided. Actually, when I tested this script using your provided access token, the result value could be obtained.
In this script, the custom function is used. So, please copy and paste the following script to the container-bound script of Google Spreadsheet. And run main(). By this, the request is run on the custom function. And, the returned value can be retrieved with the script.
function modified_pleaseWork() {
var myHeaders = { 'Authorization': 'Bearer 5cd4ac65-f71b-3eaa-93af-78610a7aa320' };
var raw = ["1111111111111"];
var requestOptions = {
'method': 'POST',
'headers': myHeaders,
'payload': JSON.stringify(raw),
'contentType': 'application/json',
};
var result = UrlFetchApp.fetch("https://www.ukrposhta.ua/status-tracking/0.0.1/statuses/last", requestOptions);
return result.getContentText();
}
// Please run this function.
function main() {
const sheet = SpreadsheetApp.getActiveSheet();
const range = sheet.getRange("A1");
range.setFormula("=modified_pleaseWork()");
SpreadsheetApp.flush();
const value = range.getValue();
range.clearContent();
console.log(value)
}

can't send multipart with fetch but axios works fine

Here is my code:
function uploadImage(payload) {
return fetch('/api/storage/upload/image/', {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data',
Accept: 'application/json',
Authorization: 'Bearer <token>',
},
body: payload,
});
}
function uploadImage2(payload) {
return axios.post('/api/storage/upload/image/', payload, {
headers: {
'Content-Type': 'multipart/form-data',
Accept: 'application/json',
Authorization: 'Bearer <token>',
},
});
}
function test(file, meta_data) {
var formBody = new FormData();
formBody.set('image', file);
formBody.set('meta_data', meta_data);
uploadImage(formBody);
// doesn't work
uploadImage2(formBody);
// works
}
Can someone please explain to me how I'm supposed to send multipart requests with fetch?
The error I get with this code is: 400 bad request, file and meta_data are null.
Do not use this header: 'Content-Type': 'multipart/form-data'.
Remove the header and it should work.
Explanation:
When using fetch with the 'Content-Type': 'multipart/form-data' you also have to set the boundary (the separator between the fields that are being sent in the request).
Without the boundary, the server receiving the request won't know where a field starts and where it ends.
You could set the boundary yourself, but it's better to let the browser do that automatically by removing the 'Content-Type' header altogether.
Here's some more insight: Uploading files using 'fetch' and 'FormData'
Here is what worked for me:
function uploadImage(payload) {
return fetch('/api/storage/upload/image/', {
method: 'POST',
headers: {
Authorization: 'Bearer <token>',
},
body: payload,
});
}
By comparing the cURL requests sent by the browser I discovered that in the axios request has this:
"Content-Type": "multipart/form-data; boundary=---------------------------19679527153991285751414616421",
So I figured that when you manually specify the content type, fetch respects that and doesn't touch anything while still does it's thing the way it wants:-/ so you just shouldn't specify it, fetch will know itself since you are using formData()

Request keeps on getting Error code: 400 - can someone please have a look on what I'm doing wrong?

Spent a few hours trying to solve this but keep on getting 400 errors. I think my payload is incorrect but not sure what I need to do.
I've tried the same request in POSTMAN with great success, and also have tried different combinations on formatting my payload (body).
I've also tried the following: var body = {"document":{"type":"PLAIN_TEXT", "content":"This is great!!"}};
function main(){
// Set the headers
var headers = {
'Authorization': 'Bearer ya29.GlyvBPhT4Y502Yo4NZ6sKI001AYlVU6om5ytXrzf2vjfEYERrsdMSBu-2ZkKir83jjj06-ewqYuBvvrx8mKfuTW1YjjlmtPmRdlK0I0Gjx',
'Content-Type': 'application/json',
'User-Agent': 'Untitled browser'
}
var uri = 'https://language.googleapis.com/v1/documents'+encodeURI(':analyzeSentiment');
var form = JSON.stringify({"document":{"type":"PLAIN_TEXT", "content":"This is great!!"}});
// Configure the request
var options = {
url: uri,
method: 'POST',
headers: headers,
form: form
}
// Start the request
request(options, function (error, response, body) {
if (!error && response.statusCode == 200) {
// Print out the response body
console.log(body)
}
else{
console.log('Error code: '+response.statusCode)
}
})
}
main();
Update - this is how it works in POSTMAN
Header is the same too:
Solved!
Need to post as body rather than form

Categories