2018 MongoDB distinct count for NodeJS Express Mongoose API - node.js

I am trying to get this value (db.collecName.distinct('fieldName').length) basically a count of distinct docs, but in a ReactJS-Express-Mongoose API route.
Should be in this format of API call :
router.get('/', function(req, res, next){
ModelName.find(function (err, CollecName){
if(err) return next(err);
res.json(CollecName);
});
});
Thanks in advance !

Thanks to Jeremy T.,
router.get('/count', function(req, res, next){
ModelName.find().distinct('fieldName', function(err, Response) {
if (err) return next(err);
// console.log(Response.length);
res.json(Response.length);
});
});
~ SOLUTION

Related

Passport req.logOut() is sending error that localhost is not sending any data

router.get('/logout', function (req, res)
{
req.logout();
req.session = null;
res.redirect('/login');
});
error-> localhost didn't send any data!
i have tried all the solutions once but still not getting the expected output !
Anykind of help is appreciated !
with express session module you can :
router.get('/logout', function (req, res)
{
req.session.destroy(function (err) {
res.redirect('/login');
});
});

mongoose: how to search mongoDB with mongoose

I am learning Express.js, MongoDB and Mongoose, and i am creating a small app that lets me store items to a list.
I am trying to Create a GET /list/search route which allows to search for items in the list, but i haven't gotten it to work.
Here is my code
Routes
const express = require('express');
router = express.Router();
const db = require("../models");
router.get('/', function(req, res, next){
db.List.find().then(function(list){
res.render('index', {list});
});
});
router.get('/new', function(req, res, next){
res.render('new');
});
router.get('/:id', function(req, res, next){
db.List.findById(req.params.id).then(function(list){
res.render('show', {list});
});
});
router.get('/:id/edit', function(req, res, next){
db.List.findById(req.params.id).then(function(list){
res.render('edit', {list});
});
});
router.get('/search', function(req, res, next){
db.List.findOne(req.query.search).then(function(list){
console.log(list);
res.render('show', {list});
});
});
router.post('/', function(req, res, next){
db.List.create(req.body).then(function(list){
res.redirect('/');
});
});
router.patch('/:id', function(req, res, next){
db.List.findByIdAndUpdate(req.params.id, req.body).then(function(list){
res.redirect('/');
});
});
router.delete('/:id', function(req, res, next){
db.List.findByIdAndRemove(req.params.id).then(function(list){
res.redirect('/');
});
});
module.exports = router;
Index.pug
extends base.pug
block content
h1 My List
form(action="/list/search" method="GET")
input(type="text" name="search")
input(type="submit", value="search")
a(href="/list/new") Add New Item!
each item in list
p ITEM: #{item.name} QUANTITY: #{item.quantity}
a(href=`/list/${item.id}/edit`) Edit
my main problem is the GET /search, i want to pass in a search query to the search box and return the result to the render file
router.get('/search', function(req, res, next){
db.List.findOne(req.query.search).then(function(list){
console.log(list);
res.render('show', {list});
});
});
Thanks in advance
You need to specify the parameters as attributes in the query. list will be null, if no matching record was found.
router.get('/search', function (req, res, next) {
db.List.findOne({
name: req.query.name,
age: req.query.age
}).then(function (list) {
console.log(list);
if (list === null) {
return res.render('show', {
list: []
});
}
return res.render('show', {
list: list
});
}).catch((err) => {
console.log('err', err);
return res.render('show', {
list: []
});
});
});

Express js routing with query string

I want to do something like this. I want to use different middleware if there is or isn't a certain query string.
app.get("/test?aaa=*", function (req, res) {
res.send("query string aaa found");
});
app.get("/test", middleware, function (req, res) {
res.send("no query string");
});
However, I failed. Can anyone help me? Thanks.
EDIT: I only need to add the middleware, I dont care what the value of the query string is
If your intention is to run the same route handler and call the middleware depending on whether the query string matches, you can use some sort of wrapping middleware:
var skipIfQuery = function(middleware) {
return function(req, res, next) {
if (req.query.aaa) return next();
return middleware(req, res, next);
};
};
app.get("/test", skipIfQuery(middleware), function (req, res) {
res.send(...);
});
If you want to have two route handlers, you could use this:
var matchQueryString = function(req, res, next) {
return next(req.query.aaa ? null : 'route');
};
app.get("/test", matchQueryString, function (req, res) {
res.send("query string aaa found");
});
app.get("/test", middleware, function (req, res) {
res.send("no query string");
});
(these obviously aren't very generic solutions, but it's just to give an idea on how to solve this)
You can do this:
app.get("/test", middleware, function (req, res) {
res.send("no query string");
});
middleware = function(req, res, next) {
if(!req.query.yourQuery) return next();
//middleware logic when query present
}

MEAN stack - trying to POST gives 404

Background:
I'm writing my first MEAN application. I'm trying to create an API that allows basic CRUD ops on a collection called "chassis".
Problem
So far, i can GET all records using find(). I can also findById, and update existing records, no problems.
However, when I try to POST, I get the following error:
dev#devbox:~/nimble_express/nimbleApp$ curl -X POST localhost:3000/chassis/ -d name=widget123 -d location=Canada -d ffd=test123 -d hw_model=hp -d asset_tag=12344
<h1>document must have an _id before saving</h1>
<h2></h2>
<pre>Error: document must have an _id before saving
at null._onTimeout (/home/dev/nimble_express/node_modules/mongoose/lib/model.js:112:18)
at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)</pre>
dev#devbox:~/nimble_express/nimbleApp$
Code
I have the following logic in a routes/chassis.js file:
var express = require('express');
var router = express.Router();
//var mongoose = require('mongoose');
var Chassis = require('../models/Chassis.js');
/* GET chassis listing. */
router.get('/', function(req, res, next) {
Chassis.find( function(err, documents) {
if (err) return next(err);
res.json(documents);
});
});
/* GET /chassis/id */
router.get('/:id', function(req, res, next) {
Chassis.findById(req.params.id, function (err, post) {
if (err) return next(err);
res.json(post);
});
});
/* POST /chassis */
router.post('/',function(req, res, next) {
console.log(req);
Chassis.create(req.body, function(err, post) {
if (err) return next(err);
res.json(post);
});
});
/* UPDATE /chassis/id */
router.put('/:id', function(req, res, next) {
Chassis.findByIdAndUpdate(req.params.id, req.body, function(err, post) {
if (err) return next(err);
res.json(post);
});
});
module.exports = router;
~
I've tried googling for this error but haven't found anything too useful yet.
Any pointers would be helpful and appreciated!

Express route for single element

I'm using express 4.9.0.
I have the following code in my user.js file inside route folder.
/* Get User by id. */
router.get('/:id', function(req, res) {
console.log('find user ' + req.params.id);
User.findById(req.params.id, function (err, user) {
if (!err) {
return res.send(user);
}
return console.log(err);
});
});
Later, in app.js:
app.use('/users', users);
However, when i navigate to http://localhost:3000/users?id=546e5640f5fea84a345abe2c the route is never hit. Calls to other routes work fine.
What am I doing wrong?
For the route you currently have, you'd need to make your request url this: /users/546e5640f5fea84a345abe2c.
If you want your route to match the request url you're currently trying (/users?id=546e5640f5fea84a345abe2c), then you would instead do:
/* Get User by id. */
router.get('/', function(req, res) {
console.log('find user ' + req.query.id);
User.findById(req.query.id, function (err, user) {
if (!err) {
return res.send(user);
}
return console.log(err);
});
});

Resources