How to handle express route callback with wagner - node.js

When I add this part of code: return function(req, res) { it not working as it should... Insede that code I tried to console log but I don't get return... If I put console log above that return I get message in console... It mean it is some problem with that part of code, but I don't know waht...
Anyone know what is issue?
I am using: express: 4.13.4
var express = require("express");
var status = require("http-status");
module.exports = function(wagner) {
var api = express.Router();
api.get("/category/id/:id", wagner.invoke(function(Category) {
return function(req, res) {
console.log("HERE");
Category.findOne({_id: req.param.id}, function(error, category) {
if(error) {
return res
.status(status.INTERNAL_SERVER_ERROR)
.json({error: error.toString()});
}
if(!category) {
return res
.status(status.NOT_FOUND)
.json({error: "Not found"});
}
res.json({category: category});
});
};
}));
}

Related

Express returns 404 even though the route exists

This is my router module:
router.post("/", function (req, res, next) {
var url = req.body.url;
youtubedl.getInfo(url, function (err, info) {
// handle errors here
if (err) {
console.log(err);
res.status(500).send("youtube-dl error");
} else {
var fields = info.title.split('-');
var artist = sanitizeArtistOrTitle(fields[0].trim());
// TODO: handle possibility of - in artist/song name
var title = sanitizeArtistOrTitle(fields[1].trim());
const options = {
apiKey: geniusKey,
title: title,
artist: artist,
optimizeQuery: true
};
geniusSong(options)
.then(function (result) {
urlFields = result.url.split('/');
// check if the name of the song and artist are in the url
// since the api seems to return a random lyric page
// when the actual page cannot be found
var titleAndArtist = urlFields[3].split('-').join(' ').toLowerCase();
if (titleAndArtist.includes(artist.toLowerCase()) &&
titleAndArtist.includes(title.toLowerCase())) {
// get the lyrics and write to a file
req.options = options;
next();
} else {
res.status(500).send("genius API error on retrieving lyrics");
}
}).catch(function (err) {
console.log(err);
res.status(500).send("genius API unknown error");
})
}
})
}, function (req, res) {
console.log(__dirname);
geniusLyrics(req.options)
.then(lyrics => sanitizeLyrics(lyrics))
.then(sanitizedLyrics => fsPromise.writeFile("./aux_files/words.txt",
sanitizedLyrics.toString()))
.then(console.log("written to file"))
.then(res.status(200).sendFile(path.join(__dirname, "../aux_files", "words.txt"),
{headers: {'Content-Type': 'text/plain'}}))
.catch(function (err) {
console.log(err);
res.status(500).send("Could not write lyrics to file");
});
})
function sanitizeLyrics(lyrics) {
var regexp = /\[[\w ]*\]/g;
return lyrics.replace(regexp, '');
}
// remove unncessary parts of the video title e.g. "feat. ...",
// "[Official Music Video]"
function sanitizeArtistOrTitle(value) {
var regexp = /(ft\..*$|\(.*$|\[.*$|feat\..*$)/
return value.replace(regexp, '');
}
module.exports = router
And in app.js I have:
var lyrics = require('./routes/lyrics');
app.use('/api/lyrics', lyrics);
What I don't understand is that the route returns a 404 when it's called by my frontend:
POST /api/lyrics 404 4400.863 ms - 351
I can see in my filesystem that the file has been written, so I know that the middleware executed successfully, but I'm not sure where the error is coming from. If I try to fetch from the route again (after the file has been created), there is no error and everything works properly.

Location API not returning location id to server

I'm following an tutorial where i am supposed to consume an mongoose API using express and display location information to the view. However I am getting an 404 error on the front end everytime i click the button that calls the API request. The source code for this tutorial can be found here. https://github.com/cliveharber/gettingMean-2/tree/chapter-07
Here is the API request handler on the server side:
const getLocationInfo = (req, res, callback) => {
const path = `/api/locations/${req.params.locationid}`;
const requestOptions = {
url: `${apiOptions.server}${path}`,
method: 'GET',
json: {}
};
request(
requestOptions,
(err, {statusCode}, body) => {
const data = body;
if (statusCode === 200) {
data.coords = {
lng: body.coords[0],
lat: body.coords[1]
}
callback(req, res, data);
} else {
showError(req, res, statusCode);
}
}
);
};
const locationInfo = (req, res) => {
getLocationInfo(req, res,
(req, res, responseData) => renderDetailPage(req, res, responseData)
);
};
The Render handler of the page i am trying to reach:
const renderDetailPage = (req, res, location) => {
res.render('location-info',
{
title: location.name,
pageHeader: {
title: location.name,
},
sidebar: {
context: 'is on Loc8r because it has accessible wifi and space to sit down with your laptop and get some work done.',
callToAction: 'If you\'ve been and you like it - or if you don\'t - please leave a review to help other people just like you.'
},
location
}
);
};
This is the Mongoose API controller that retrieves the location data from the database:
const locationsReadOne = (req, res) => {
Loc
.findById(req.params.locationid)
.exec((err, location) => {
if (!location) {
return res
.status(404)
.json({
"message": "location not found"
});
} else if (err) {
return res
.status(404)
.json(err);
}
res
.status(200)
.json(location);
});
};
This is the express routing code:
const express = require('express');
const router = express.Router();
const ctrlLocations = require('../controllers/locations');
const ctrlOthers = require('../controllers/others');
router.get('/', ctrlLocations.homelist);
router.get('/locations/:location._id', ctrlLocations.locationInfo);
And finally this is a snippet of the Pug code that contains the button which calls the get request to retrieve the location id:
each location in locations
.card
.card-block
h4
a(href=`/locations/${location_id}`)= location.name
+outputRating(location.rating)
span.badge.badge-pill.badge-default.float-right= location.distance
p.address= location.address
.facilities
each facility in location.facilities
span.badge.badge-warning= facility
Let me know if i need to provide additional information. Appreciate any help.

How to pass data from model to router in Node.js

I'm new to Node.js and am trying to pass some data from my DB model back to the router but I'm unable to find a solution. I have the following route file that makes a call to model:
Route file:
var express = require('express');
var router = express.Router();
var db = require('../db');
var customers = require('../models/customers');
db.connect(function(err) {
if (err) {
console.log('Unable to connect to MySQL.')
process.exit(1)
}
});
router.post('/', function(req, res) {
customers.checkPassword(req.body.cust_id, req.body.password);
res.sendStatus(200);
});
Model file:
var db = require('../db.js');
module.exports.checkPassword = function(cust_id, password) {
var sql = "SELECT Password FROM Shop.customers WHERE ID =" + cust_id;
db.get().query(sql, function (err, res, fields) {
result = res[0].Password;
if (err) throw err
});
};
My question is: how could I pass the queried result Password back to my Route file so that I can do this:
console.log('Password is', result);
I appreciate any help on this.
I'd use a promise
Model file
module.exports.checkPassword = function(cust_id, password) {
return new Promise(function(resolve, reject) {
const sql = "SELECT Password FROM Shop.customers WHERE ID =" + cust_id;
db.get().query(sql, function (err, res, fields) {
if (err) return reject(err)
result = res[0].Password;
return resolve(result);
});
});
};
Route file
var express = require('express');
var router = express.Router();
var db = require('../db');
var customers = require('../models/customers');
db.connect(function(err) {
if (err) {
console.log('Unable to connect to MySQL.')
process.exit(1)
}
});
router.post('/', function(req, res) {
customers.checkPassword(req.body.cust_id, req.body.password)
.then((result) => {
// DO: something with result
res.status(200).send();
})
.catch(console.log); // TODO: Handle errors
});
With async/await
router.post('/', async function(req, res) {
try {
const result = await customers.checkPassword(req.body.cust_id, req.body.password)
// DO: something with the result
} catch (e) {
console.log(e); // TODO: handle errors
} finally {
res.status(200).send();
}
});
I assume console.log('Password is', result); is just for test prupose, obviously you should never log a password! Also I suggest to move the callbabck of the routes do a different module, to improve code redability.
You might also find useful promise-module module on npm, basically a promise wrapper around mysql.
You can delegate the credential control to another function in your DB file where you can decide on what kind of data you want to return on success and failure to find such data. Then you can access it from where you are calling it.

Express: Show value from external request as response

I have the following function where I am using the cryptocompare npm package:
getPrice: function(coin){
cc.price(coin, 'USD')
.then(prices => {
console.log(prices);
return prices;
}).catch(console.error)
}
// https://github.com/markusdanek/crypto-api/blob/master/server/helper/cryptocompare.js
Now I want to set up an Express server to open http://localhost:9000/current and to display the current "price".
So I have my controller which looks like this:
module.exports = {
getCurrentPrice: function(req, res, next) {
getPrice('ETH', function(price);
}
};
// https://github.com/markusdanek/crypto-api/blob/master/server/controllers/CryptoController.jshttps://github.com/markusdanek/crypto-api/blob/master/server/controllers/CryptoController.js
My route:
var controllers = require('../controllers'),
app = require('express').Router();
module.exports = function(app) {
app.get('/current', controllers.crypto.getCurrentPrice);
};
When I open now http://localhost:9000/current I only get the current price in my console, but not in my browser.
How can I also set the response to the value?
I tried this but failed:
module.exports = {
getCurrentPrice: function(req, res, next) {
getPrice('ETH', function(price){
res.status(200).json(price);
});
}
};
I guess thats the wrong way to call a callback.. do I have to modify my helper function or anything else?
My project is also on Github for further references: https://github.com/markusdanek/crypto-api
below may help you
module.exports = {
getCurrentPrice: function(req, res, next) {
cc.price('ETH', 'USD')
.then(prices => {
console.log(prices);
res.json(prices)
})
.catch(err=>{
console.error(err)
return next(err);
})
}
};

Deploying to Heroku with node.js & express - how to setup connection to mongoLab?

Alright, first time posting here, so I'm hoping I get some feedback.
I have two collections that I've successfully uploaded into
mongoLab/mLab, their names are "allTest" and "myCollection".
I want to deploy my site to heroku (which I've successfully done
already) and be able to pull and display data from mLab.
Everything was working great when I was running locally and pulling
from mongoDB, so I know its because I want to pull from mLab instead of my local instance of mongoDB. However, I'm confused on how to setup the connection to mLab when its deployed on Heroku.
I've read some documentation that I should use URI (which I listed below),
but I'm not sure what else I should change in my code.
Here is what I have so far (I edited out my username and password in the URI):
var express = require("express");
var mongojs = require("mongojs");
var logger = require("morgan");
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser());
var uri = 'mongodb://USERNAME:PASSWORD#ds157702.mlab.com:57702/heroku_r45mjcns';
app.use(express.static("public"));
var databaseUrl = "mydb";
var collections = ["myCollection"];
var databaseUrl2 = "testMenu";
var collections2 = ["allTests"];
var db = mongojs(databaseUrl, collections);
var db2 = mongojs(databaseUrl2, collections2);
app.get("/", function(req, res) {
res.sendfile('public/home.html');
});
app.get("/find2/:id", function(req, res) {
var test_id2 = req.param('id');
db2.allTests.find({"TestName": {$regex:test_id2, $options: 'i'} }, function(error, found) {
// Log any errors if the server encounters one
if (error) {
console.log(error);
}
// Otherwise, send the result of this query to the browser
else {
res.json(found);
console.log("From server");
console.log(found);
}
});
});
app.get("/find/:id", function(req, res) {
var test_id = req.param('id');
db2.allTests.find({"Test": test_id }, function(error, found) {
// Log any errors if the server encounters one
if (error) {
console.log(error);
}
// Otherwise, send the result of this query to the browser
else {
res.json(found);
console.log("From server");
console.log(found);
}
});
});
app.get("/find/dept/:id", function(req, res) {
var test_id = req.param('id');
db.myCollection.find({ $or: [ { "WebsiteCategory": test_id }, { "WebsiteCategory2": test_id } ] }, function(error, found) {
// Log any errors if the server encounters one
if (error) {
console.log(error);
}
// Otherwise, send the result of this query to the browser
else {
res.json(found);
console.log("From server");
console.log(found);
}
});
});
app.get("/find/dept2/:id", function(req, res) {
var test_id = req.param('id');
db.myCollection.find({"TestSet": test_id }, function(error, found) {
// Log any errors if the server encounters one
if (error) {
console.log(error);
}
// Otherwise, send the result of this query to the browser
else {
res.json(found);
console.log("From server");
console.log(found);
}
});
});
// Set the app to listen on port 3000
app.listen(process.env.PORT || 3000);
`
Specifically, its this piece of code that I was trying out:
app.get("/find/dept/:id", function(req, res) {
var test_id = req.param('id');
db.myCollection.find({ $or: [ { "WebsiteCategory": test_id }, { "WebsiteCategory2": test_id } ] }, function(error, found) {
// Log any errors if the server encounters one
if (error) {
console.log(error);
}
// Otherwise, send the result of this query to the browser
else {
res.json(found);
console.log("From server");
console.log(found);
}
});
});
Any help would be appreciated!!

Resources