I am trying to a get request to an API.
This is what I have in Angular
Service:
angular.module('MyApp')
.factory('Search', function($resource) {
return $resource('/api/show/:search');
});
Ctrl:
$scope.$watch('searchStr', function (tmpStr)
{
if (!tmpStr || tmpStr.length == 0)
return 0;
// if searchStr is still the same..
// go ahead and retrieve the data
if (tmpStr === $scope.searchStr) {
console.log(Search);
Search.get({string: $scope.searchStr})
.$promise.then(function(data) {
console.log(data);
$scope.responseData = data;
})
}
});
View:
<input type="text" data-ng-model="searchStr">
<textarea> {{responseData}} </textarea>
Nodejs so far:
app.get('api/show/:search', function(req, res, next) {
request.get('http://thetvdb.com/api/GetSeries.php?seriesname=' + search, function (error, response, body) {
console.log('error', error);
console.log('response', response);
console.log('BODY', body);
});
});
what I need is to get a response from that link above when the user is searching, but all I get is the response from the first get to api/show/:search, what am I missing?
replace search with req.params.search
app.get('api/show/:search', function(req, res, next) {
request.get('http://thetvdb.com/api/GetSeries.php?seriesname=' + req.params.search, function (error, response, body) {
console.log(error, response, body);
});
});
Related
My res.json in my first block of code works, but in the else part of my if statement, it does not. The block that doesnt work, checks for a record in a database then im trying to return the response but im not receiving it.
I've checked and the response is a string, I thought it would have worked as the top part of the code successfully returns the string and it shows in dialogflow (where im trying to return it)
The response is successfully consoled right before the res.json but I do not receive it from the source of the request.
code:
app.post('/webhook/orderinfo', (req, res) => {
const intent = req.body.queryResult.intent.displayName;
const domain = "chatbotdemo.myshopify.com";
const order = req.body.queryResult.parameters["number-sequence"];
if (intent.includes('Order Number')) {
url = "https://test-hchat.com/api/orders/" + domain + "/" + order;
request(url)
.then(function (response) {
order_res = JSON.parse(response)
order_res["fullfillmentText"] = "Hi, Please find your order details below:";
res.json({
"fulfillmentText": JSON.stringify(order_res)
})
})
.catch(function (err) {
console.log(err)
});
// THIS PART DOESNT RETURN THE RESPONSE.
} else {
const domain = 'testStore'
db.getClientsDialog(domain, intent, (response) => {
const fullResponse = response.response
res.json({
fullResponse
})
})
}
});
The database code:
getClientsDialog: function (domain, intent, callback) {
MongoClient.connect('mongodb://efwefewf#wefwef.mlab.com:15799/wefwef', function (err, client) {
if (err) throw err;
var db = client.db('asdsad');
db.collection('dialog').findOne({ domain: domain, intent: intent }, function (err, doc) {
if (!err) {
callback(doc)
} else {
throw err;
callback(err)
}
client.close();
});
console.dir("Called findOne");
});
}
Could it be because this second use of the res.json in the else statement, is trying to call the db first and therefore the link is lost to send the data back?
I am making a skill for the Amazon Echo. In my handlers, I have an intent (SelectGardenIntent) that obtains the user_id (needed for following HTTP requests) from the access token successfully, as well as a variable called gardenNumber which is a slot value. To complete the request, I need two other values, the garden_id and the dev_id. I use this gardenNumber and pass it into a function called getGardenId, which will assign the one of the data from the HTTP request to the variable garden_id I have defined in index.js. There are no issues with user_id and gardenNumber. When the function is run, there are no errors from the request, but the callback function with the response is also not executed. The user_id, "about to enter request", and "req done" are correctly logged when tested, but the other log statements in the callback function are not since it is not run. The result is that garden_id is undefined. dev_id is obtained in another method that depends on this garden_id, so dev_id is also undefined. Please help me on this issue. I have pasted the relevant code below.
...
var user_id, garden_id, dev_id;
...
function getGardenId (gardenNumber) {
console.log(user_id);
var path = '/api/rest/client/getgardeninfo?&userid=' + user_id;
var options = {
hostname: server_ip,
port: 80,
path: path,
method: 'GET'
}
console.log("about to enter request");
var req = http.request(options, (res) => {
console.log('entered request');
if (res.statusCode === 200) {
console.log('successful request');
res.setEncoding('utf8');
var body = "";
res.on('data', (chunk) => {
console.log('adding data');
body += chunk.toString();
});
res.on('end', () => {
var obj = JSON.parse(body);
console.log('successfully parsed');
if (obj.error === 200) {
console.log('##gardenid successfully obtained');
garden_id = obj.data[gardenNumber - 1].id;
} else {
console.log("parsing error");
}
});
} else {
console.log("failed request");
}
}); } catch(e) {
console.log("ERROR");
}
req.on('error', (e) => {
console.error(`problem with request: ${e.message}`);
});
req.on('finish', () => {
console.log('ended');
})
req.end();
console.log("req done");
}
...
var handlers = {
...
'SelectGardenIntent': function () {
//var filledSlots = delegateSlotCollection.call(this);
var gardenNumber = this.event.request.intent.slots.Garden.value;
user_id = this.event.session.user.accessToken;
getGardenId(gardenNumber);
getDevId(garden_id);
this.emit(':tell', `OK, garden ${gardenNumber} selected, user id is ${user_id}, garden id is ${garden_id}, device id is ${dev_id}`);
}
...
}
You'd better use npm request to make calls.
request.get({
url: 'http://' + server_ip + '/api/rest/client/getgardeninfo?&userid=' + user_id
}, function (err, res, body) {
console.log(body);
})
For a personal project I'm trying to create a simple oEmbed system using Nodejs.
My route looks like this:
app.get('/oembed/:url', function (req, res) {
oembed.get(req.params.url, function (error, result) {
return res.json(200, {message: "OK"});
});
});
and oembed is exposed using var oembed = require('../oembed');
For the oembed.js itself I have:
var request = require('request');
exports.get = function(url, callback) {
//this bit will be developed to call different functions depending on the URL
html = vimeo(url)
};
function vimeo(url) {
var videoUrl = url;
var endpoint = 'http://www.vimeo.com/api/oembed.json';
var url = endpoint + '?url=' + encodeURIComponent(videoUrl) + '&width=640';
request(url, function (error, response, body) {
if (!error && response.statusCode == 200) {
var video = JSON.parse(body);
return video.html
}
})
}
So far, the vimeo function returns the desired html to the function call but I'm a bit lost from here. I'm not sure how I return the html to the initial request (the oembed.get part) and utilise the callback's error and result parameters.
Any help (and advice) would be much appreciated.
It seems you just don't understand how callback functions work. You need something like this in your oembed.js file:
var request = require('request');
exports.get = function(url, callback) {
var endpoint = 'http://www.vimeo.com/api/oembed.json';
request(endpoint + '?url=' + encodeURIComponent(url) + '&width=640', function (error, response, body) {
if (!error && response.statusCode == 200) {
try {
callback(null, JSON.parse(body).html);
} catch (error) {
callback(error);
}
}
});
};
And your route should look like this:
app.get('/oembed/:url', function (req, res) {
oembed.get(req.params.url, function (error, result) {
if (error) {
res.json(500, {message: error});
} else {
res.json(200, {message: "OK"});
}
});
});
I have a form whose submit button calls
exports.postUpdateProfile = function(req, res, next) {
User.findById(req.user.id, function(err, user) {
if (err) return next(err);
user.email = req.body.email || '';
user.profile.name = req.body.name || '';
//check req.body.rescueTimeKey by making http request,
//and parsing response to ensure the key is good
user.profile.rescueTimeKey = req.body.rescueTimeKey;
user.save(function(err) {
if (err) return next(err);
req.flash('success', { msg: 'Profile information updated.' });
res.redirect('/account');
});
});
};
I want to make sure the req.body.rescueTimeKey is valid before saving the profile, I've tried to create a module to perform that check...
//rescue-time.js module
var request = require('request');
exports.validKey = function(key){
var options = {
url: 'https://www.rescuetime.com/anapi/data?key=' + key,
json: true
};
var cb = function callback(error, response, body){
if(error || body.error){
//Key is bad, flash message and don't allow save
}
//key is good, save profile
};
request(options, cb);
}
As you might imagine I am not fully grasping the node style of using callbacks when making async calls, any help to re-organize this code is greatly appreciated.
What you will want to do is add an extra argument to your validKey function to accept a callback which is what we will use after the request.
So your rescue-time.js will look something like this:
// rescue-time.js
var request = require('request');
exports.validKey = function(key, cb) {
var options = {
url: 'https://www.rescuetime.com/anapi/data?key=' + key,
json: true
};
request(options, function (error, response, body) {
if(error || body.error){
cb(false)
}
else {
cb(true);
}
});
};``
We're returning a boolean result of true or false if the key is valid.
Inside your controller you will want something like the following:
var rescueTime = require('./path/to/rescue-time.js');
exports.postUpdateProfile = function(req, res, next) {
User.findById(req.user.id, function(err, user) {
if (err) return next(err);
user.email = req.body.email || '';
user.profile.name = req.body.name || '';
//check req.body.rescueTimeKey by making http request,
//and parsing response to ensure the key is good
user.profile.rescueTimeKey = req.body.rescueTimeKey;
// We're sending in a callback function that will have a "valid" result as a second arg
rescueTime.validKey(user.profile.rescueTimeKey, function(valid) {
// check if valid returned true or false and act accordingly
if (!valid) {
req.flash('error', 'invalid rescueTime key');
res.redirect('/account');
}
else {
user.save(function(err) {
if (err) return next(err);
req.flash('success', { msg: 'Profile information updated.' });
res.redirect('/account');
});
}
});
});
};
Keep in mind this code wasn't tested at all, but more of an example on what you need to do to obtain your desired results.
I'm very new to Nodejs and i'm trying to find a record in my db(mongo) by submitting a code and crosschecking the record to see if it exists.
I'm not really clear on how to approach this to get to an endresult stating "There is a code, please continue" and "There is no code".
This is what i have so far as a result of my fiddling:
userProvider.js:
UserProvider.prototype.findByCode = function(code, callback) {
this.getCollection(function(error, user_collection) {
user_collection.findOne({code: code}, function(error, result) {
callback(error, result)
});
});
}
The get collection belonging to userProvider.js:
UserProvider.prototype.getCollection= function(callback) {
this.db.collection('users', function(error, user_collection) {
if( error ) callback(error);
else callback(null, user_collection);
});
};
app.js:
app.post('/game/code', function(req, res) {
if (req.param('code')) {
userProvider.findByCode(req.param('code'), function(error, result) {
console.log(error);
console.log(result);
});
}
});
And the jade form submitting the code:
extends layout
block content
h1= "Gimme a code"
div
form( method="post")
div
div
span.label code :
input(type="text", name="code", id="code")
div
input(type="submit", value="Verbind")
Console logging the param('code') results in the code. So i'm pretty sure that one's solid. So why's there a null returned?
From the question, you didn't say where the 'null' was returned. I am new to nodejs as well, however I noticed in your code:
app.post('/game/code', function(req, res) {
if (req.param('code')) {
userProvider.findByCode(req.param('code'), function(error, result) {
console.log(error);
console.log(result);
});
}
});
and you didn't call the 'res' object. You should try something like this:
app.post('/game/code', function(req, res) {
if (req.param('code')) {
userProvider.findByCode(req.param('code'), function(error, result) {
if(error)
res.send(404, 'There is no code');
else {
console.log(result);
res.send('There is a code:'+result);
}
});
}
});
Check out http://expressjs.com/api.html#res.status for various things you do with res object