Youtube search API results not displaying in the EJS file - javascript

I am implementing YouTube Search API in my Website, when I am calling the api from my route the results are returned but the page is rendered while the results are being computed, I guess because of the asynchronous behavior.
My route through which I am calling the API:
router.get('/video/results/:search_query', middleware.ensureAuthenticated, function (req, res) {
query = req.params.search_query;
console.log(query);
var dataFinal;
var resp = youtube.search.list({
part: 'snippet',
q: query,
type: 'video'
},function (err, data, response) {
if (err) {
console.error('Error: ' + err);
res.json({
status: "error"
});
}
if (data) {
// console.log(typeof data);
dataFinal = data;
// return res.json({
// status: "ok",
// data: data
// });
console.log(data);
//res.render('resultsVideo',{results:data})
}
});
res.render('resultsVideo',{data:dataFinal})
});
Please tell me how can I call the API and use the results in my EJS file to display.

you can use function callback to get the desired result.
router.get('/video/results/:search_query', middleware.ensureAuthenticated, function (req, res) {
query = req.params.search_query;
console.log(query);
var dataFinal;
function resp() = youtube.search.list({
part: 'snippet',
q: query,
type: 'video'
},function (err, data, response) {
if (err) {
console.error('Error: ' + err);
res.json({
status: "error"
});
}
if (data) {
// console.log(typeof data);
return data;
// return res.json({
// status: "ok",
// data: data
// });
console.log(data);
//res.render('resultsVideo',{results:data})
}
});
res.render('resultsVideo',{data:resp()})
});

Related

Check that email exists with Node within API

Introduction
Ok, I have Three functions. the first two generate data for the third.
Gets post data (email)
Gets API key
Uses API key, User_key and email and post them to the API
What I need
I need the third to print the following to my console providing the email is present.
else {
console.log("Login successful !");
console.log("API Key", api);
console.log("userKey", userkey);
console.log("useremail", login_email);
console.error("Third You have logged in !");
}
What I am getting
error null
I am getting this even though I post a email that exist. Dose anyone see where I am going wrong in my code ?
Node Code
var firstFunction = function () {
var promise = new Promise(function (resolve) { // may be redundant
setTimeout(function () {
app.post('/test.js', function (req, res) {
console.log(req.body);
// Get varibles from the post form
var login = req.body.LoginEmail;
// res.send(email_user);
res.send(login);
//resolve when get the response
resolve({
data_login_email: login
});
});
console.error("First done");
}, 2000);
});
return promise;
};
//---------------------------------- Function to get API key from Pardot (AUTHENTICATION) ------------------------------
//----------------------------------------------------------------------------------------------------------------------
var secondFunction = function () {
var promise = new Promise(function (resolve) {
setTimeout(function () {
nodePardot.PardotAPI({
userKey: userkey,
email: emailAdmin,
password: password,
DEBUG: false
}, function (err, client) {
if (err) {
// Authentication failed
console.error("Authentication Failed", err);
} else {
// Authentication successful
var api_key = client.apiKey;
console.log("Authentication successful !", api_key);
resolve({data_api: api_key});
}
});
console.error("Second done");
}, 2000);
});
return promise;
};
//---------------------------------- Function to post data to Pardot ---------------------------------------------------
// ---------------------------------------------------------------------------------------------------------------------
function thirdFunction(result) {
var promise = new Promise(function () {
setTimeout(function () {
var headers = {
'User-Agent': 'Super Agent/0.0.1',
'Content-Type': 'application/x-www-form-urlencoded'
};
// Configure the request
var api = result[1].data_api;
var userEmail = result[0].data_login_email;
var options = {
url: 'https://pi.pardot.com/api/prospect/version/4/do/read',
method: 'POST',
headers: headers,
form: {
'email': userEmail,
'user_key': userkey,
'api_key': api
}
};
// Start the request
request(options, function (error, response) {
if (!error && response.statusCode == 200) {
console.log("error", error);
}
else {
console.log("Login successful !");
console.log("API Key", api);
console.log("userKey", userkey);
console.log("useremail", login_email);
console.error("Third You have logged in !");
}
});
}, 3000);
});
return promise;
}
// sequence of functions
Promise.all([firstFunction(), secondFunction()])
.then(thirdFunction);

nodejs express response append into a list

I have multiple res.send in one route, how can I append them all into one and send the accumulated list at the end?
I prefer to do it in the following form:
{
"writer": {success message},
"archive": {success message},
...
}
and another one like above for the list errors.
here is the code:
router.post('/some/route', function (req, res) {
if (req.isLoggedIn()) {
return res.status(403).json({});
}
MyModel.findById(req.user._id,function (err, data) {
if(err || data.rights !== 'super'){
return res.status(403).json({});
}
if(req.body.writer){
Books.update(
{ writer : req.body.id},
{ $set : { writer : req.body.writer} },
function (err) {
if(err){
res.status(500).send(err);
}
else{
res.status(200).send('updated successfully.');
}
}
);
}else{
Books.remove({writer: req.body.id}, function(err){
if (err){ return console.log(err)}
});
}
MetaInfo.findOneAndRemove({_id: req.body.id}, function (err, data) {
console.log(err);
});
Archive.findOne({_id: req.body.id},function (err, data) {
smtpTransporter.sendMail({...}, function (error, response) {
if (error) {
console.log(error);
} else {
console.log("Mail sent");
}
smtpTransporter.close();
});
data.remove();
if (err) {
console.log(err);
return res.status(200).json({
success: false,
message: 'server error',
err: err
});
}
res.status(200).json({
success: true
});
})
});
});
I assume your problem are the asynchronous calls to the database.
So best take a library of your choice (for example async) and do your async processes, in the callback then finally send your result.
Your result could look like this:
async.parallel([
function(callback) { ... },
function(callback) { ... }
], function(err, results) {
// send your result here
});
Note that if you are using .parallel the final callback will be immediatly called if one of the promises fails. see the docu

node/express.js - forEach loop with request to API pushes result to array, but array remains empty

Here is a snippet from my express.js file:
function playlistTracks(req, res) {
var tracks = [];
var genres = ['hi'];
var playlistOption = {
url: 'https://api.spotify.com/v1/users/' + req.params.user + '/playlists/'+ req.params.id + '/tracks',
headers: { 'Authorization': 'Bearer ' + access_token },
json: true
};
rp(playlistOption)
.then(function (body) {
tracks = body;
return tracks;
})
.then(function (tracks) {
getGenre(tracks);
res.render('tracks', {
data: tracks
});
})
.catch(function (err) {
console.log('couldnt get tracks' , err);
throw err;
});
function getGenre(tracks) {
tracks.items.forEach(function(e){
var reqGenre = {
url: 'https://api.spotify.com/v1/artists/' + e.track.album.artists[0].id,
json: true
};
rp(reqGenre)
.then(function(body) {
genres.push(body.genres)
})
.catch(function(err){
console.log('couldnt get genres' , err);
throw err
});
});
io.emit('playlists', {genres: genres});
console.log(genres) // <---empty
}
}
the "getGenre" function is where I have the most trouble with. I want to know how I can update the "genres" array with that function. I've tried a couple of solutions but can't seem to get my head around the async nature of a request.
I've looked at this and other solutions already, but can't figure out how to apply them to my code.
I'm using request-promise to get the api request.
getGenre fetches data async, so you can try such code:
function playlistTracks(req, res) {
var tracks = [];
var playlistOption = {
url: 'https://api.spotify.com/v1/users/' + req.params.user + '/playlists/'+ req.params.id + '/tracks',
headers: { 'Authorization': 'Bearer ' + access_token },
json: true
};
rp(playlistOption)
.then(function (body) {
tracks = body;
return tracks;
})
.then(function (tracks) {
getGenre(tracks);
res.render('tracks', {
data: tracks
});
})
.catch(function (err) {
console.log('couldnt get tracks' , err);
throw err;
});
function getGenre(tracks) {
var promises = tracks.items.map(function(e){
var reqGenre = {
url: 'https://api.spotify.com/v1/artists/' + e.track.album.artists[0].id,
json: true
};
return rp(reqGenre)
.then(function(body) {
return body.genres
})
.catch(function(err){
console.log('couldnt get genres' , err);
throw err
});
});
return Promise.all(promises).then(function(results) {
var genres = ['hi'].concat(results);
io.emit('playlists', {genres: genres});
console.log(genres)
});
}
}

Updating mongodb with angularjs and node

I need to update my mongodb using nodejs and angularjs on the front end. I have the below code but i get error like `TypeError: Cannot read property 'put' of undefined
My angularjs controller :
myApp.controller('userController', ['$scope', '$resource', 'AuthService','iden','$http', function ($scope, $resource, AuthService,iden,$http) {
console.log(usersOnline);
var Meetup = $resource('/api/user', {},{
query: {method: 'get', isArray: true}
});
$scope.users = [];
$scope.userss = [];
$scope.text='mikyas';
Meetup.query({text: usersOnline}).$promise.then(function (results) {
$scope.users = results;
}, function(error) {
// console.log(error);
$scope.meetups = [];
});
console.log(usersOnline);
function getUser(iden,$http) {
//return promise here
var Users = $resource('/api/users', {},{
query: {method: 'get', isArray: true}
});
$scope.usersOnline='a';
return Users.query({username: usersOnline}).$promise
//other code as is
}
$scope.id='cpasgrave';
$scope.lol=getUser();
$scope.lol.then(function(user,$http){
console.log(user[0]._id);
iden=user[0]._id;
$scope.userss = user;
console.log(iden);
$http.put('/api/updateUser' + user[0]._id, user[0]);
});
console.log(iden);
}]);
And my api on the server side :
*
module.exports.updateUser = function (req, res) {
var id = req.body.id;
User.findById(id, function(err, user) {
if (err) throw err;
// change the users location
user.auto = 'true';
// save the user
user.save(function(err) {
if (err) throw err;
console.log('User successfully updated!');
});
});
}
`
Remove the $http argument in your $scope.lol.then(function(user,$http) function.
$scope.lol.then(function(user){
console.log(user[0]._id);
iden=user[0]._id;
$scope.userss = user;
console.log(iden);
$http.put('/api/updateUser' + user[0]._id, user[0]);
});
Also, if you define getUser (iden, $http), make sure you put correct arguments when you call it...
$scope.id='cpasgrave';
$scope.lol=getUser(iden, $http);
try replacing this:
$http.put('/api/updateUser' + user[0]._id, user[0]);
});
with this:
$http({
method: 'PUT',
url: '/api/updateUser' + user[0]._id, user[0]
}).then(function successCallback(response) {
console.log('put success');
}, function errorCallback(response) {
console.log('put failed');
});

Node JS - Busboy retrieve parameters

I'm now stuck with my project using NodeJS and Busboy.
I'm trying to retrieve all the variables from my router and send it to controllers.
app.js (routes)
router.post('/product', function (req, res) {
var fields = {};
req.busboy.on('field', function(fieldname, val) {
fields[fieldname] = val;
});
req.busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
fields[filename] = file;
});
req.pipe(req.busboy);
productController.addNewProduct(fields, function (data) {
res.json(data);
});
});
ProductController.js
addNewProduct: function (params, callback) {
productLogic.addNewProduct(params, function (data) {
callback(data);
});
},
ProductLogic.js
addNewProduct: function (params, callback) {
Product.findOne({ name: params.name }, function (err, product) {
if(err) callback({ status: false, message: err });
if(product)
callback({ status: false, message: 'Produk sudah ada.' });
var newProduct = new Product({
name: params.name,
category_id: params.category_id,
description: params.description,
is_active: true
});
newProduct.save(function (err, result) {
if(err) callback({ status: false, message: err });
callback({ status: true, message: result });
});
});
},
My goal is to process the data all at once. And now I'm not sure if I can achieve it with busboy.
Please help me on this.
Bunch of thanks in advance
You should wait for busboy to finish parsing your form before calling your method.
busboy.on('finish', function() {
productController.addNewProduct(fields, function (data) {
res.json(data);
});
});
I think I already found the answer.
Thanks to marton for the heads up.
I've tried:
busboy.on('finish', function() {});
but it never emitted.
The reason is I have to file.resume() in my busboy.on('file'), example:
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
fields[fieldname] = file;
file.resume();
Once again thanks :)

Categories