I've created a route in a Node.js project to render all "logs" from a MongoDB database to a Web page:
app.get('/api/logs', function (req, res) {
Log.find( function (err, logs) {
res.json(logs);
});
});
I want to modify this query to (1) limit the response to 10 logs and (2) display the logs in reverse chronological order (from most recent to least recent). If I try the below code, nothing will render to my page and my Node server gives the following error: Error: sort() only takes 1 Argument.
app.get('/api/logs', function (req, res) {
Log.find().limit(10).sort({$natural:-1}, function(err, logs){
res.json(logs);
});
});
The above snippet DOES work if I type it directly into my Monog console as a single query: Log.find().limit(10).sort({$natural:-1}) Is there a different way to write this to grab the information I want? Thanks for your suggestions!
This works perfectly:
app.get('/api/logs', function (req, res) {
Log.find().limit(10).sort(-fieldToSort).exec(function(err, logs){
res.send(logs)
})
});
The -fieldToSort sorts the field in a descending order as you requested. fieldToSort is the field name you want to sort.
Hope it helps!
Related
I am trying to make a GET request so that it only returns the last item stored in my database. I can get the answer I want in the mongo shell (see below), but I'm at a loss as to how to compose the query in my GET route. I am using ejs templates, so I will also need to pass the response through the res.render as well. I am still kind of new to programming so forgive me if this question isn't as concise as it should be.
My mongo shell query:
Blog.find().sort({_id:-1}).limit(1)
I hope the code below gives you a hint on how to structure your code using express and EJS.
app.get("/", async (req, res) => {
try {
const blogItem = await Blog.find().sort({_id:-1}).limit(1);
// Render the page with the result
res.render("your-page.ejs", { blog: blogItem });
} catch (error) {
// Handle errors here
res.render("500.ejs");
throw error;
}
});
I am using a simple get request using mongoose coupled with express and node to fetch all the documents in a particular collection I have defined in a MongoDB instance. It works fine for small amounts of data but is failing for large datasets. I am able to run the same query on Mongo Shell and after a decent amount of time, it is able to return the data.
I have tried to modify the query to use lean() function along with the find({}) function of mongoose but the problem still persists.
/*
Fetch all the players
GET - /
*/
getPlayerRouter.route('/')
.get((req, res, next) => {
Player.find({}).lean()
.then((players) => {
res.status(200).json({
success: true,
totalPlayers: players.length,
players
});
})
.catch((err) => console.log(err));
});
I expect the query to fetch all the documents on the collection.
var query=Player.find({}).stream();
query.on('data', (players)=> {
res.status(200).json({
success: true,
totalPlayers: players.length,
players
});
}).on('error',(err)=>{
}).on('close',()=>{
console.log('connection closed');
});
You can use stream in mongoose to process large records.Comment on whether it works.
I'm using Angular-Fullstack generator, and I'm not able to get a list of drivers depending on a companyID, through $resource query. This is what I have:
server/api/driver/index.js:
router.get('/:company', controller.index);
server/api/driver/driver.controller.js:
export function index(req, res) {
return Driver.find({company: req.params.company}).exec()
.then(function(res){
console.log(res); /* I get here the result correctly */
respondWithResult(res)
})
.catch(handleError(res));
}
client/services/driver.service.js:
export function DriverResource($resource) {
'ngInject';
return $resource('/api/drivers/:id/:company', {company: '#_id'});
}
client/app/driver/driver.controller.js:
this.driverList = Driver.query({company: Auth.getCurrentUser()._id}});
console.log(this.driverList); /* Empty array */
I'd be grateful if someone could help me getting the response from the server...
Thank you in advance.
I just realised that I was duplicating the 'res' variable:
server/api/driver/driver.controller.js:
export function index(req, res) {
return Driver.find({company: req.params.company}).exec()
.then(function(**res**){
/* Should be the result, not the response */
console.log(**res**);
respondWithResult(**res**)
})
.catch(handleError(res));
}
You were close.
Driver.query({company: 'foo'}).$promise.then(function(results) {
console.log(results) //here
}, function(err) {
//here is your 404 error, but you should create an http interceptor
});
It's async, do you don't get your results right away.
This will work of course, assuming your backend responds properly.
EDIT: Your backend is missing some endpoints. You should be able to respond to requests to /api/drivers/ with a list of drivers
EDIT 2:
Angular's resource will give you access to some methods:
Driver.get(1) Will make a request to /api/drivers/:id and will be expecting the backend to respond with an object representing the driver with said ID. This should be used when you want to fetch only 1 record
Driver.query({foo: 'bar', some_id: 1}) Will make a request to /api/drivers?foo=bar&some_id=1 and will be expecting the backend to respond with an array of objects, each representing a driver. This should be used when you want to fetch several records, for example in an index.
Driver.query() will make a request to /api/drivers and will be expecting the backend to respond with an array
Driver.create(data) will make a POST request to /api/drivers and will expect an object (the created driver) in the response. Used to create a new record
There are some others, this is the ones I use.
So, your backend, considering you are using this three methods, needs to handle:
router.get('/drivers/:id', function(req, res) {
let id = req.params.id
})
router.get('/drivers', function(req, res) {
//if request was /drivers?foo=bar
let foo = req.query.foo
})
router.post('/drivers', function(req, res) {
let body = req.body
})
As I said, there are several things in play here. If you are at a lost, break the problem into pieces. Get the backend working before going to Angular.
I am want to create web server that will return data for my mobile app. I use Node.js for server and SQLite3 for database. I created method that must return data from sql, but I don't know how to do it correctly. As I know all methods from SQLite lib are async so I have no idea how to do sync request for DB. I tried this way:
app.get('/getAllLeagues',function (req, res) {
console.log("get")
var obj = db.all("SELECT name FROM Leagues")
})
But seems that obj is still the same as db object
I'm assuming that your app is an express server instance or similar. The database query function takes a callback function that is called once the queried rows are ready or an error is found.
app.get('/getAllLeagues',function (req, res) {
console.log("get")
var obj = db.all("SELECT name FROM Leagues",
function(err, rows) {
res.type('json');
res.send(rows);
});
});
For simplicity, there is no error handling. It is better to try..catch a similar request to avoid crashing your app in case the database or the table is not found.
I've checked two similar questions here and neither of the things suggested in the comments are working for me.
app.get('/:id', function(req,res) {
console.log(req.params.id);
});
app.get('/:id', function(req, res) {
db.query("SELECT * FROM entries WHERE id = $1", [req.params.id], function(err, dbRes) {
if (!err) {
res.render('show', { entry: dbRes.rows[0] });
}
});
});
As you can see, I've tried logging the result to the console to see what's going on. Visiting the URL in question just makes the page load until it times out. In the console, I get "undefined".
How do I define req.params? Or where is it's definition being pulled and why isn't it returning the values?
Full context: http://pastebin.com/DhWrPvjP
Just tested your code and it works fine. I think you might be missing your url parameter. It should be http://localhost:3000/1 - or whatever ID you're trying to retrieve. Try it out.
Also, you should pass the extended option to your bodyParser.urlencode method: express throws error as `body-parser deprecated undefined extended`
Edit: To specifically answer your question about defining request parameters. You don't have to do anything to define request parameters other than make sure that you're passing in the correct URL. Express takes care of parsing the URL and defining the request parameters for you. So, if you go to the URL http://localhost/jimbob on your server then the value passed in for the id parameter will be available as req.params.id. See this link on request parameters for more info.
Edit 2: You could try debugging your app to see what you get. Here's a link on how to enable debugging in Express and how to use node-inspector for debugging. I saw that your running this on Ubuntu. So, there may be something weird there that I'm not aware of. (I'm running it on a Mac.)
I would also check the version of Node that you're running on the computer(s) that the app works on and check the version of Node on your Ubuntu environment (or whatever computers the app doesn't work on).
app.get('/:id', function(req, res) {
db.query("SELECT * FROM entries WHERE id = $1", [req.params.id], function(err, dbRes) {
if (!err) {
res.render('show', { entry: dbRes.rows[0] });
}
});
});
in your code the url would be localhost/some-id req.params.id would equal some-id, params are pulls straight from the url string, if you are trying to send info with post or get methods you want to use req.body and req.query respectively. I dont see any reason you wouldnt be able to get the id unless the url is wrong
or if you need to do it manually
app.get('/:id', function(req, res) {
//if no req.params and assuming the id is the last item in the url
var urlArray = req.url.split('/'),
id = urlArray[urlArray.length-1];
db.query("SELECT * FROM entries WHERE id = $1", [req.params.id], function(err, dbRes) {
if (!err) {
res.render('show', { entry: dbRes.rows[0] });
}
});
});
try this req.param('id') :D. It may be working for you
I know I'm late to the party but this post helped me debug my issue so I figured I'll add my suggestion in hopes it will help someone else.
If you are using mysql2 with promises
const mysql = require("mysql2");
const pool = mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE
});
module.exports = pool.promise();
Then you need to use promises in your request.
router.get("/:id", (req, res) => {
mysql
.execute("SELECT * FROM entries WHERE id = $1", [req.params.id])
.then(result => {
res.send(result[0]);
})
.catch(err => {
console.log(err);
});
});
I spent hours debugging my code only to realize I was using promise() in my connection. Hope this helps as this post helped me debug.