When I make a POST request to a website, the JSON response body posts 'undefined'. However, it correctly prints the response body content in the form of name/value pair objects to the console when I call console.log(body).
Why is the body 'undefined' when I post the content to the website?
Response body:
const options = {
method: 'GET',
url: 'https://url.com',
content: {count: '3'},
headers: {}
};
Calls to body:
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
const params = {
status: request.body
}
M.post('statuses', params) => {
console.log(params.request);
};
Related
I make a POST request from my browser client:
const post = async (url, body) => {
try {
const response = await fetch(url, {
method: `POST`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body
});
return response.json();
} catch (error) {
console.log(error.stack);
}
}
const data = await post(`http://localhost:4050/analyze`, { text });
And I handle it on Express server with this setup:
app.use(express.urlencoded({ extended: true }));
This is my route:
router.post(`/`, errorHandler(async (req, res, next) => {
const { text } = req.body;
console.log(req.body)
const value = await analyze(text);
res.json({ rephrased });
}));
The console.log shows me this:
{ 'object Object': '' }
Why fetch method gives me Object instead of text property?
UPDATE:
When I do Stringify:
method: `POST`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: JSON.stringify(body)
The body became like this and console.log shows:
{ '{"text":"asdfasdf"}': '' }
You are passing fetch a plain object for the body and it doesn't know what to do with it, so it calls .toString() and gives you nothing useful.
Pass it a URLSearchParams object instead. (Here I assume text is a string)
const body = new URLSearchParams();
body.append("text", text);
This will convert to a application/x-www-form-urlencoded string.
(You can also omit the headers as fetch can infer the correct Content-Type from the URLSearchParams object.)
Re edit: JSON.stringify will encode the data as JSON. JSON is not application/x-www-form-urlencoded.
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.
I am receiving a request response in the console.log, however when I try to post to Mastodon (similar site to Twitter), it posts as 'undefined'.
bot.js:
require('dotenv').config();
const Mastodon = require('mastodon-api');
var request = require('request');
console.log("Mastodon Bot starting...");
const M = new Mastodon({
access_token: process.env.ACCESS_TOKEN,
client_key: process.env.CLIENT_KEY,
client_secret: process.env.CLIENT_SECRET,
timeout_ms: 60*1000,
api_url: 'https://botsin.space/api/v1/',
})
const options = {
method: 'GET',
url: 'https://apisite.com/steps',
qs: {count: '3'},
headers: {
'X-RapidAPI-Key': 'secret-api-key',
'X-RapidAPI-Host': 'site-host',
useQueryString: true,
},
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(JSON.parse(body, undefined, 5));
});
const params = {
status: request
}
M.post('/statuses', params, (error, params) => {
if (error) {
console.log(error);
}
else {
console.log(params.request);
}
});
This posts "Mastodon bot is starting...", then the results of the API GET request to the console (the response body).
However, it does not post the response body to /statuses in Mastodon itself, it just posts 'undefined'.
How can I post the response body that I get in the console, to Mastodon?
I want to pass the value in API request body.
I tried below code for that
var options = { method: 'POST',
url: 'https://ssgpreprod.serviceurl.in/gonogo-api/atm/tw/cro-approval',
headers:
{ 'Postman-Token': '9d6a0ad1-c3a1-402f-b845-b6416f49df6b',
'cache-control': 'no-cache',
'Content-Type': 'application/json' },
body:
{ oHeader:
{ sReqType: 'application/json',
sAppSource: 'WEB 2.02.01',
sSourceID: 'GONOGO_HDBFS',
sAppID: 610961419000670,
dtSubmit: '',
sCroId: 'HDB_TW_CRO#cell.com',
sDsaId: 'default',
sInstID: 4019,
sUserName: 'CHDBTWCRO',
sProduct: 'TW',
sDealerId: '61096' },
sRefID:testData.twPreIpa.twReferenceId,
sAppStat: testData.twCroDetails.twCroDecision,
aCroJustification: [ { sRemark: testData.twCroDetails.twRemark, sSubTo: testData.twCroDetails.twSubjectTo} ],
bApprAmtExist: true,
dApprAmt: testData.twApplyDetails.twLoanAmount,
dItrRt: testData.twCroDetails.twRoi,
dLtv: testData.twCroDetails.twLtv,
aDedupeRefID: [] },
json: true };
request(options, function (error, response, body) {
if (error) throw new Error(error);
browser.logger.info(JSON.stringify(body));
browser.logger.info(JSON.stringify(response));
browser.logger.info('status code is : ' + response.statusCode);
expect(response.statusCode).toBe(200).then(function () {
browser.logger.info('case is approved');
this.logOut(testData);
})
});
I am passing value from xlsx file i.e testData.twPreIpa.twReferenceId but I am getting 422 status code and below output
[2019-05-28 15:42:10.403] [INFO] : - {"title":"Conversion Failed","status":422,"detail":"The content you've sent is probably malformed."}
Also, when I add - browser.logger.info('approved'); above var options it prints on console.. but when I add - browser.logger.info(testData.twPreIpa.twReferenceId);
It gives me error .. ouput displayed -
Failed: Cannot read property 'twReferenceId' of undefined
TypeError: Cannot read property 'twReferenceId' of undefined
While this may not directly answer your question it should be helpful to you.
I worked on a similar framework to what (I assume) yours looks like,some api and some UI validations.
I had a separate class for my API calls which returned some value, sometimes the entire response body. I allowed myself the ability to pass in whatever body I needed as a parameter.
This is an example of the approach I took.
module.exports = class Endpoints {
addSomethingToUser(bearerToken, userId, JSONbody) {
//Function will preform a POST request and return the status code if successful
//Else if will return the body of the response
let endpoint = 'http://myApp.com:9090/api/users/' + userId;
return new Promise((resolve, reject) => {
let options = {
method: "POST",
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token,
},
body: JSON.stringify(JSONbody),
};
request(
endpoint,
options ,
function (error, response, body) {
if (!error && (response.statusCode >= 200 && response.statusCode < 300)) {
resolve(response.statusCode);
} else {
console.log('error:', error, response && response.statusCode);
reject(JSON.stringify(response, undefined, 2));
};
}
);
});
};
}
It is called like
let apiCallsFile = require('../apiCalls/restCalls');
let apiCalls = new apiCallsFile();
it('simple test', async function(){
let requiredBody = {
"NAME": "Test Name",
"GENDER": "MALE",
};
let apiResult = await apiCalls.addSomethingToUser(bearerToken, userId, requiredBody );
expect(apiResult).toBe('201');
}
Your issue seems to be related to the actual values you are using from excel. You should attempt to print out your values before attempting to send the request to ensure they are all present and in the format you expect.
I'm calling a simple login API with POST request following are the params:
Headers:
Content-type: application/x-www-form-urlencoded
Body:
email: String
password
Error returned from server is:422 Unprocessable Entity
CODE:
var formBody = new FormData();
formBody.set("email", "test5#gmail.com");
formBody.set("password", "12345678");
const data = new URLSearchParams(new FormData(details));
return dispatch => {
dispatch(requestData());
try {
fetch(`${BASE_URL}users/sign_in`, {
method: 'POST',
// headers: Interceptor.getHeaders(),
headers: {
Accept:'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
// body: formBody
body: data
})
.then(res => res.json())
.then(result=>
{
if (result.success === false) {}
}
)
} catch (error) {
console.log('error',error)
dispatch(failureData(error))
}
}
Screenshot of code
Got the answer, 422 is basically caused by semantic issue, in my case, Origin of my Request Header was going null.