$.ajax call node js equivalent? - javascript

I am not very familiar with Node js and as well as dealing with http requests so pardon me if this is something obvious.
I am following the examples on this website:
$.ajax({
url: 'https://api.wit.ai/message',
data: {
'q': 'set an alarm in 10min',
'access_token' : 'MY_WIT_TOKEN'
},
dataType: 'jsonp',
method: 'GET',
success: function(response) {
console.log("success!", response);
}
});
I am trying to create the equivalent of this but in Node Js. I attempted to use 'node request' however my code is not working. I have attempted a lot of variations of this but to no avail.
Here is an example:
var request = require('request');
var url = 'https://api.wit.ai/message';
var data = {
'q': 'hello test123 trying to get entities from this message',
'access_token': 'MY_WIT_TOKEN'
};
request.get({ url: url, formData: data }, function (err, httpResponse, body) {
if (err) {
return console.error('post failed:', err);
}
console.log('Get successful! Server responded with:', body);
});
When I compile this code, my terminal replies with:
Something went wrong. We've been notified.

Use http:
var http = require('http');
http.get({
host: 'api.wit.ai',
path: '/message'
}, function(response) {
var body = '';
// get all data from the stream
response.on('data', function(data) {
body += data;
});
response.on('end', function() {
// all data received
console.log(body)
});
});

To anyone interested here is the answer using node request that worked for me.
var request = require('request');
var headers = {
'Authorization': 'Bearer <WIT_TOKEN>'
};
var options = {
url: 'https://api.wit.ai/message?v=20160607&q=hello',
headers: headers
};
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
}
request(options, callback);

Related

How to combine API GET request in nodejs?

I have several API Get request at once in nodejs. Each API have new data every couple minutes.
var express = require('express');
var router = express.Router();
var request = require("request");
let value1, value2, bodyData1, bodyData2;
var options = { method: 'GET',
url: 'https://api.example.com/data1',
qs:
{
valueType: 'MAXIMUM'
},
headers:
{
authorization: 'ABC123456',
accept: 'application/json; charset=utf-8' } };
request(options, function (error, response, body) {
if (error) throw new Error(error);
bodyData1 = JSON.parse(body);
value1 = bodyData1.value;
});
var options = { method: 'GET',
url: 'https://api.example.com/data2',
qs:
{
valueType: 'MAXIMUM'
},
headers:
{
authorization: 'ABC123456',
accept: 'application/json; charset=utf-8' } };
request(options, function (error, response, body) {
if (error) throw new Error(error);
bodyData2 = JSON.parse(body);
value2 = bodyData2.value;
});
router.get('/', function(req, res, next) {
res.render('home', {valueA : value1, valueB: value2});
});
module.exports = router;
I want to know if it is possible to combine them into one function?
Any other things I should concern?
It is possible if you have promises which is currently not the case. You have to wrap your request() call in a Promise. You can do it manually with a custom function requestToPromise.
You can then use Promise.all to call multiple promises in parallel.
function requestToPromise(options) {
return new Promise((resolve, reject) => {
request(options, (error, response, body) => {
if (error) return reject(error);
resolve(body);
});
});
}
var optionsRequest1 = {
method: "GET",
url: "https://api.example.com/data1",
qs: {
valueType: "MAXIMUM"
},
headers: {
authorization: "ABC123456",
accept: "application/json; charset=utf-8"
}
};
var optionsRequest2 = {
method: "GET",
url: "https://api.example.com/data2",
qs: {
valueType: "MAXIMUM"
},
headers: {
authorization: "ABC123456",
accept: "application/json; charset=utf-8"
}
};
var requestPromise1 = requestToPromise(optionsRequest1);
var requestPromise2 = requestToPromise(optionsRequest2);
Promise.all([requestPromise1, requestPromise2]).then(results => {
var [resultPromise1, resultPromise2] = results;
}).catch(error => {
//handle error
});
Instead of using the custom function requestToPromise you can also use util.promisify
const util = require('util');
const requestAsync = util.promisify(request);
Promise.all([requestAsync(optionsRequest1), requestAsync(optionsRequest2)]).then(results => {
var [resultPromise1, resultPromise2] = results;
}).catch(error => {
//handle error
});
You can use Redis cache to store data in memory for fast retrieval and fetch from memory very quickly.
Also, after some interval, you can add them to a database through bulk creation. It will decrease your database call.
// Example in sequilize
await db.table_name.bulkcreate([ {0bj1}, {obj2}..,{obj3 } ]);

Accessing data within object

app.get('/profile/:id', function(req, res){
var options = { method: 'GET',
url: 'https://api.favoriot.com/v1/streams?max=1',
headers:
{ 'cache-control': 'no-cache',
'content-type': 'application/json',
'apikey': 'api key' } };
request(options, function (error, response, body) {
res.render('profile', {data:body});
console.log(body)
});
});
when I run code above, I get this data:
{"debugCode":null,"statusCode":200,"numFound":1,"results":[{"user_id":"xxx510","stream_created_at":"2019-03-05T16:13:01.982Z","stream_developer_id":"f8b8fcb9-6f3e-4138-8c6b-d0a7e8xxxxx#xxxx510","device_developer_id":"raspberryPIxx#xxx510","data":{"distance":"12.4","status":"1"}}]}
how can I make it only display status only?
AFAIK there is no issue with the code as such. Are you sure that you got the distance and status in the data field of body or is it the intended output? By try using their API playground by setting your API key on it. I have rewritten the code using ES6 standards by promisifying request module or you can use the request-promise-native.
function requestPromisified(options) {
return new Promise(function(resolve, reject) {
request(options, function(error, res, body) {
if (!error && res.statusCode == 200) {
resolve(body);
} else {
reject(error);
}
});
});
}
app.get("/profile/:id", async (req, res) => {
const options = {
method: "GET",
url: "https://api.favoriot.com/v1/streams?max=1",
headers: {
"cache-control": "no-cache",
"content-type": "application/json",
apikey: "api key"
}
};
try {
const body = await requestPromisified(options);
console.log(body);
res.render("profile", { data: body });
} catch (error) {
res.status(400).send('Unable to find a profile')
}
});
1) There is no middleware in this example... you're just making a call to get some data.
2) status is available in body.results[0].data.status so just use that instead of the entire body object

About node.js return data to ajax call function

Now I have a question like this:
I created a server with node.js ,and the server have receive a ajax request.With the data received from ajax ,node.js send a post request to another server. Now I have got the data from another server and the main question is how to send the data back to ajax, I have tried many ways but it does not work.
Can somebody help me on this issue?
here is my code
====ajax request
$.ajax({
type: "POST",
url: 'http://localhost:8888', // 这里要改成服务器的地址
data: userData,
success: function (data) {
console.log(data);
}
})
====
http.createServer(function (req, res) {
if (req.url == '/') {
var data = '';
var imdata;
util.log(util.inspect(req));
util.log('Request recieved: \nmethod: ' + req.method + '\nurl: ' + req.url);
req.on('data', function (chunk) {
imdata = querystring.parse(data += chunk);//转成对象的格式
})
req.on('end', function () {
var myIm = new ServerApi('e782429e48cb99f44b9c5effe414ac72', 'b88b9f2a2f74');
myIm.createUserId(imdata, function (err, data) {
//createUesrId is a api to deal with post request
console.log(data);//the data have received from another server,and now i do not know how to return the data to ajax success function
})
})
====the api to create user id with post requeset
ServerApi.prototype.postDataHttps = function (url, data, callback) {
this.checkSumBuilder();
var urlObj = urlParser.parse(url);
var httpHeader = {
'AppKey': this.AppKey,
'Nonce': this.Nonce,
'CurTime': this.CurTime,
'CheckSum': this.CheckSum,
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
'Content-Length': Buffer.byteLength(data)
};
var options = {
hostname: urlObj.hostname,
port: 80,
path: urlObj.path,
method: 'POST',
headers: httpHeader
};
var that = this;
var req = http.request(options, function (res) {
res.setEncoding('utf8');
console.log("statusCode: ", res.statusCode);
console.log("headers: ", res.headers);
res.on('data', function (chunk) {
if (Object.prototype.toString.call(callback) === '[object Function]') {
var result = JSON.parse(chunk);
callback.call(that, null, result);
return result;
}
});
});
var postData = querystring.stringify(data);
req.write(postData);
req.end(data);
req.on('error', function (err) {
if (Object.prototype.toString.call(callback) === '[object Function]') {
callback.call(that, err, null);
}
});
}
ServerApi.prototype.createUserId = function (data, callback) {
var url = 'https://api.netease.im/nimserver/user/create.action';
var postData = {
'accid': data['accid'] || '',
'name': data['name'] || '',
'props': data['props'] || '',
'icon': data['icon'] || '',
'token': data['token'] || ''
};
this.postDataHttps(url, postData, callback);
}
On your server code. The one with http.createServer(function (req, res) {...}
Notice how you got a req and res parameter?
So on event end, that is req.on('end' function... Right after the line where you got a comment saying the 'data is received from another server', you can do something like;
res.writeHead(/*HTTP_RESPONSE_CODE_FOR_AJAX_CLIENT=*/200);
res.end('Done');
to send a response back to your client with HTTP response code = 200 and the message in the HTTP body would be 'Done'. Note that, there are quite a number of things you can do with the response object, you may want to see the documentation for more information.
See:
https://nodejs.org/api/http.html#http_response_writehead_statuscode_statusmessage_headers
OR
(中文版)
http://nodeapi.ucdok.com/api/http.html#http_class_http_serverresponse_7847
Quick explanation in Chinese:
在服务器的代码req.on('end'...那里, 你可以用resobject打回给你的AJax client.

Arguments passed from request library are received but they aren't received when the arguments are sent from URL

I have a node.js server and I'm making GET requests.
The arguments passed using Python's requests and JavaScripts's request are received properly.
// Python
requests.get(url, data=data)
// JS
request.get({url: url, form:form}, function(){})
But the data is not received when I make the request from a browser like: url?a=1&b=2.
How do I fix it?
This is the function that I'm using to parse the form data:
function extractData(request, response, callback, options) {
var jsonString = '';
request.on('data', function(data) {
jsonString += data;
});
request.on('end', function() {
data = qs.parse(jsonString);
callback(request, response, data, options);
});
}
data is blank when I pass the arguments from URL.
I hope this will be helpful and below code is working to me
var options = {
host: 'services.com',
path: '/app/server.js/index/',
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Content-Length': data.length
}
};
var req = https.request(options, function(res) {
var msg = '';
res.setEncoding('utf8');
res.on('data', function(chunk) {
msg += chunk;//'chunk' response from server
if(chunk != "available")
{
var mail = {
from: "abc#gmail.com",
to: "ddd#gmail.com",
subject: "Alert! from production server",
html: "<p>Hi Team,</p> <p>Alert! production server is down.</p><p>Thanks,<br/>Maintenance Team</p>"
};
transporter.sendMail(mail, function(error, response){
if(error){
console.log(error);
//res.send({ "result" : "failure" });
}else{
console.log("Message sent: " + response);
//res.send({ "result" : "success" });
}
});
}
});
res.on('end', function() {
//console.log(JSON.parse(msg));
console.log(msg);
});

Post Method works using https.request but not with Needle or Request libraries

I have nodeApp. It does stuff.
At a particular time I need to communicate with an API that out there in the wild. Using the API in rest tool like Postman is straight forward:
Postman
Url:
https://epicurl
Headers:
Content-Type : application/json
Accept : application/json
x-key : secret
Body:
{
"some":"kickass"
"data":"here"
}
Sending the above in Postman I get a nice quick response! Yay for rest tools.
So their API works, now I need to make that same response in my Node.js application.
This is where things get odd...
Request Module: FAILS
var request = require('request')
...lots_of_other_stuff...
var options = {
uri: 'https://epicURL',
method: 'POST',
json: true,
headers : {
"Content-Type":"application/json",
"Accept":"application/json",
"x-key":"secretbro"
},
body : JSON.stringify(bodyModel)
};
request(options, function(error, response, body) {
if (!error) {
console.log('Body is:');
console.log(body);
} else {
console.log('Error is:');
logger.info(error);
}
cb(body); //Callback sends request back...
});
The above fails.. It throws the good'ol ECONNRESET error that we all love! Why? Who knows?
https.request() - WORKS!
var https = require("https");
https.globalAgent.options.secureProtocol = 'SSLv3_method';
var headers = {
"Content-Type":"application/json",
"Accept":"application/json",
"x-key":"nicetrybro"
}
var options = {
host: 'www.l33turls.com',
port:443,
path: "/sweetpathsofjebus",
method: 'POST',
headers: headers
};
var req = https.request(options, function(res) {
res.setEncoding('utf-8');
var responseString = '';
res.on('data', function(data) {
responseString += data;
});
res.on('end', function() {
var resultObject = responseString;
//Call the callback function to get this response object back to the router.
cb(resultObject);
});
});
req.on('error', function(e) {
console.log(e);
});
req.write(bodyString);
req.end();
But then I notice...
If i leave this line of code in place when using the Request Module it then works...
var https = require("https");
https.globalAgent.options.secureProtocol = 'SSLv3_method';
Is this documented somewhere and I am missing it? Anyone explain this to me?

Categories