I write API in order to client upload file. API has content-type multiple/form-data. But I don't know get values from client send to my
router.post('/upload/file', async (req, res) => {
var body = "";
try {
req.on('data', function (chunk) {
body += chunk;
});
req.on('end', function () {
console.log('body: ' + body);
var formData = new FormData(body);
console.log("=====================", formData.entries);
// var {accessTok, type, file} = req.params;
//
// if (!accessTok || !type || !file) {
res.json({
code: -1000,
message: 'Missing parameter(s). Please provide accessToken, type upload, file upload.'
});
res.end();
return null;
})
// }
}catch(err){
res.json({err: err.message});
res.end();
return;
}
I tried use FormData but not done. I get error is not function, formData.getKey('') is them same.
Related
helper.js
exports.instaToken = async (code) => {}
const formData = new FormData();
formData.append('client_id', KEY_ID);
formData.append('client_secret', KEY_SECRET);
formData.append('grant_type', 'authorization_code');
formData.append('redirect_uri', REDIRECT_URI);
formData.append('code', code);
let response = formData.submit('https://api.instagram.com/oauth/access_token', function (err, res, body) {
if (err) {console.log(err)};
console.log(body);
// console.log(res.resume());
console.log(res.statusMessage);
console.log(res.statusCode);
return res;
});
index.js
router.get('/token', async (req, res, next) => {
try {
let token = 'AQD-uIrveubzTktAysHM7yjSJvqJUueUU9B6r-hhfMer63-uUqSIldjuAyA-fdlm1DICbT9SsR06hWj78hWlAS4Xs--Sq3tyIAZPyIl2Xu72EiMF1WKyh1Jzf1eLUMsQsoHsJFYyjx-RP1pYXOporQrLmI2mRknSkbc3xJIKaXwbnYlonTTSW3B5pJ0n8qDS5jSwoM7gKFl7rTNPAGPd745pY44T18Npkz2UWBCVb_ebNA';
let response = await instaHelper.instaToken(token);
req.data = response;
req.status = 200;
req.message = 'Token Fetched Successfully';
next();
}
catch (e) {
req.status = 400;
next(e);
};
});
I want to get response after submission of form but response is coming after hitting API and there is something buffer returning after in response but I want response to be returned which is coming after submission of form. Any help will be apricated.
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
I have created a nodejs express application using Express Generator.
In its route index.js I'm trying to make a rest api call using default HTTP module in the standard library https://nodejs.org/api/http.html#http_http_get_options_callback (I do not want to install external dependencies)and that would provide the values for title and welcome text in the view. Below is the code for index.js.
var express = require('express');
var router = express.Router();
const http = require('http');
/* GET home page. */
router.get('/', function(req, res, next) {
let titletext = '';
let wtext = '';
http.get('http://localhost:5000/api/values', (apires) => {
const { statusCode } = apires;
const contentType = apires.headers['content-type'];
let error;
if (statusCode !== 200) {
error = new Error('Request Failed.\n' +
`Status Code: ${statusCode}`);
} else if (!/^application\/json/.test(contentType)) {
error = new Error('Invalid content-type.\n' +
`Expected application/json but received ${contentType}`);
}
if (error) {
console.error(error.message);
// Consume response data to free up memory
apires.resume();
return;
}
apires.setEncoding('utf8');
let rawData = '';
apires.on('data', (chunk) => { rawData += chunk; });
apires.on('end', () => {
try {
const parsedData = JSON.parse(rawData);
console.log(parsedData);
titletext=parsedData[1];
wtext=parsedData[0];
} catch (e) {
console.error(e.message);
}
});
}).on('error', (e) => {
console.error(`Got error: ${e.message}`);
});
res.render('index', { title: titletext, data:wtext });
});
module.exports = router;
But it does not seem to be working and titletext and wtest were coming as empty strings. So, I added three breakpoints. One just after the get call, second after get call response comes and the last on the page response render call(res.render) at the very end.
Now when I run, I find that the get call breakpoint gets called,then the page response render call breakpoint gets called and finally the get call response breakpoint gets called, the data comes from the rest api but by then the page render call is already over and so the data from api call does not reach the view.
Any ideas how to solve this is sincerely appreciated
Http request call is async, so if you put res.render at the end of GET handler, it will render empty data before request returns response.
Following the document, you should parse response's body and render page from end event handler, like:
router.get('/', function(req, res, next) {
let titletext = '';
let wtext = '';
http.get('http://localhost:5000/api/values', (apires) => {
const { statusCode } = apires;
const contentType = apires.headers['content-type'];
let error;
if (statusCode !== 200) {
error = new Error('Request Failed.\n' +
`Status Code: ${statusCode}`);
} else if (!/^application\/json/.test(contentType)) {
error = new Error('Invalid content-type.\n' +
`Expected application/json but received ${contentType}`);
}
if (error) {
console.error(error.message);
// Consume response data to free up memory
apires.resume();
return;
}
apires.setEncoding('utf8');
let rawData = '';
apires.on('data', (chunk) => { rawData += chunk; });
apires.on('end', () => {
try {
const parsedData = JSON.parse(rawData);
console.log(parsedData);
titletext=parsedData[1];
wtext=parsedData[0];
// Render page here
res.render('index', { title: titletext, data:wtext });
} catch (e) {
console.error(e.message);
}
});
}).on('error', (e) => {
console.error(`Got error: ${e.message}`);
});
// Not here
});
There's the code in my project which try to get an access token from wechat.
router.get('/', function(req, res, next) {
var params = new URLSearchParams({
grant_type: config.grantType,
appid: config.appID,
secret: config.appSecret
});
const url = config.wechat + '?' + params.toString();
http.get(url, (res) => {
console.log("haha");
console.log(res);
var rawData = '';
if (res.statusCode != 200) {
res.resume();
console.error('statusCode:' + res.statusCode);
return;
}
res.on('data', function (chunk) {
rawData += chunk; //buffer data if has
console.log(rawData);
});
res.on('end', function() {
try {
console.log("haha");
const accessTokenData = JSON.parse(rawData);
console.log("access: " + accessTokenData);
var newToken = new AccessToken({
token: accessTokenData["access_token"],
record_time: Date.now(),
expires: accessTokenData["expires_in"]
});
newToken.save(function(err) {
console.log("save error: " + err);
});
} catch (e) {
console.error('parse error: ' + e);
}
});
}).on('error', function(e) {
console.error("get access token failed: " + e);
});
console.log("sadfdas");
});
what I want to do is getting access token from the api and store it into mongodb using mongoose. when I start node service on my local vagrant machine and access the route, there is nothing printed on the terminal and new record inserted into mongodb. So I don't know where's the problem, I'm sure that the url is right, which I have tested with postman. Please help me find the problem. Any help will be appreciated.
I'm fumbling my way through node.js with massive help from people on here and I'm struggling getting the body of a GET request into a variable.
Here's the code so far:
var speechOutput;
var myCallback = function(data) {
console.log('got data: '+data);
speechOutput = data;
};
var usingItNow = function(callback) {
var http = require('http');
var url = 'http://services.groupkt.com/country/get/iso2code/IN';
var req = http.get(url, (res) => {
var body = "";
res.on("data", (chunk) => {
body += chunk;
});
res.on("end", () => {
var result = JSON.parse(body);
callback(result);
});
}).on('error', function(e){
console.log("Got an error: ", e);
});
};
usingItNow(myCallback);
I'm using examples from other posts to try and get the body of the GET request into the speechOutput variable but it is coming out as undefined.
Ultimately I want the RestResponse.result.name in speechOutput, but I thought I would take this one step at a time. Can anyone offer any pointers?
Further to this, I have tried the following, which still came back undefined - maybe there is a bigger issue with the code? It doesn't even seem to be getting to the parse.
res.on("end", () => {
// var result = JSON.parse(body);
callback('result');
});
putting the line callback('result'); before the line var req = http.get(url, (res) => { returns 'result' but anything else is either undefined or causes an error.
Quoting Roy T. Fielding:
Server semantics for GET, however, are restricted such that a body,
if any, has no semantic meaning to the request. The requirements
on parsing are separate from the requirements on method semantics.
Don't use get request to send body parameters. Use post requests. If you want to send data within a get request, add them to the query string.
Read this for more info about bodies in get requests:
HTTP GET with request body
Update:
Try to log errors in the response, add this before you set up the listeners:
var body = "";
const { statusCode } = res;
const contentType = res.headers['content-type'];
let error;
if (statusCode !== 200) {
error = new Error('Request Failed.\n' +
`Status Code: ${statusCode}`);
} else if (!/^application\/json/.test(contentType)) {
error = new Error('Invalid content-type.\n' +
`Expected application/json but received ${contentType}`);
}
if (error) {
console.error(error.message);
// consume response data to free up memory
res.resume();
return;
}
res.on("data", (chunk) => {
body += chunk;
});
I found this example to get body, but how can I retrive the req.param variable? I do not have req in this case?!
app.post('/:tableName', function(res){
var data = '';
res.on('data', function (chunk){
data += chunk;
});
res.on('end',function(){
var obj = JSON.parse(data);
var schema = require('./schema/' + req.param('tableName'));
var record = new schema(obj);
record.save(function(err) {
if (err) {
console.log(err);
res.status(500).json({status: 'failure'});
} else {
res.json({status: 'success'});
}
});
})
});
UPDATE
I modified the method signature like this, but then first res.on will not get called.
app.post('/:tableName', function(req, res) {
Your callback should take in req and res, but is currently only taking in req as res.
app.post('/:tableName', function(req, res){ should give the function what it expects.