Cannot Getting data from url query parameters. from a node rest api - node.js

I have this code to make a get, post, put and delete request,
const express = require("express");
const TutorialModel = require("../models/tutorialModel");
const router = express.Router();
router.post("/tutorials", async (req, res) => {
try {
const tutorial = new TutorialModel(req.body);
const createTutorial = await tutorial.save();
res.status(201).send(createTutorial);
} catch (e) {
res.status(400).send(e);
}
});
router.get("/tutorials", async (req, res) => {
try {
const TutorialsData = await TutorialModel.find();
res.status(200).send(TutorialsData);
} catch (e) {
res.status(404).send(e);
}
});
router.get("/tutorials/:id", async (req, res) => {
try {
const _id = req.params.id;
const TutorialData = await TutorialModel.findById(_id);
if (!TutorialData) {
res.status(404).send();
} else {
res.send(TutorialData);
}
} catch (e) {
res.status(500).send(e);
}
});
router.get("/tutorials/:title", async (req, res) => {
try {
const _title = req.params.title;
const TutorialData = await TutorialModel.find({ title: _title });
if (!TutorialData) {
res.status(404).send();
} else {
res.send(TutorialData);
}
} catch (e) {
res.status(500).send(e);
}
});
router.put("/tutorials/:id", async (req, res) => {
try {
const _id = req.params.id;
const updateTutorial = await TutorialModel.findByIdAndUpdate(
_id,
req.body,
{ new: true }
);
res.send(updateTutorial);
} catch (e) {
res.status(400).send(e);
}
});
// Deleting student data by its Id
router.delete("/tutorials/:id", async (req, res) => {
try {
const _id = req.params.id;
const deleteTutorial = await TutorialModel.findByIdAndDelete(_id);
if (!_id) {
return res.status(400).send();
} else {
res.send(deleteTutorial);
}
} catch (e) {
res.status(500).send(e);
}
});
router.delete("/tutorials", async (req, res) => {
try {
const deleteTutorial = await TutorialModel.remove();
if (!deleteTutorial) {
return res.status(400).send();
}
else {
res.send(deleteTutorial);
}
} catch (e) {
res.status(500).send(e);
}
});
module.exports = router;
I've successfully made all request including get request with 'id' But when I try to make get request using 'title' parameter I'm getting data of get request of "/tutorials" not of "tutorials/:title". What is the issue? Can anyone tell me please?

The route GET "/tutorials/:id" will catch all your GET requests like /tutorials/something. It does not distinguish if you pass an id or a title.
:id is used to tell Express to capture the something path in the URL in req.params.id. That's all.
If you want to have another route to get tutorials by title, you should use another form. For example, GET "/tutorialsByTitle/:title".

Related

I need to Update one record in mongodb?

router.patch('/edit/:id', async (req, res) => {
try {
let id = req.params.id;
let updateData = req.body;
const result = await Category.updateOne(id,updateData);
if(result) {
res.status(200).send({
result: result
});
}
}
catch (err) {
for (field in ex.errors) {
res.status(500).send(ex.errors[field].message);
}
}
})
This is my code but its not Working data not changed in records when i call this function

Fastify async try catch does not resolve

I have simple route:
fastify.post('/subscribe', {
schema: subscribeSchema,
handler: async (req, reply) => {
try {
const events = req.body.events;
const allEventsProcessingData = await Promise.all(events.map(async (ev) => {
return {
event: ev,
feedEventsData: await getFeedEventData(ev),
feedMainMarketsData: await getFeedEventMainMarketsData(ev),
}
}));
// process HTML by events data
// allEventsProcessingData
const compiledHTML = '';
return reply.send(compiledHTML);
} catch (e) {
console.log('e', e);
return reply.send(HTTP_RESPONSES.FAIL);
}
}
});
When error happens, the response does not send, why is it? And how to send it? Tried this https://github.com/fastify/fastify/issues/1864#issuecomment-534233381, but it did not work.

data will not goto backend in mongodb using vue.js

backend will work when i using postman but when i using frontend for storing data only id will goes to database
here my frontend code where i declare method:-
methods: {
feedbackData() {
let KisanData1 = {
name1: this.name1,
village: this.village
};
console.log(KisanData1);
axios
.post('http://localhost:3000/User', KisanData1)
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error);
});
}
backend code where i insert data:-
app.post('/User', (req, res) => {
console.log(req.body);
User.create(req.body).then((message) => {
res.json(message);
}).catch((error) => {
res.status(500);
res.json(error);
});
});
and create method in mongodb:-
function create(message) {
const result = Joi.validate(message, UserSchema);
if (result.error==null) {
message.created = new Date();
return info.insert(message);
} else {
return Promise.reject(result.error);
}
}

fastify-mongodb : "mongo" is undefined when accessed

I'm attempting to use Fastify and fastify-monogdb.
Currently I have the following...
In my /src/index.js
const routes = require("./routes");
const fastify = require("fastify")({
logger: true
});
routes.forEach((route, index) => {
fastify.route(route);
});
fastify.register(require("fastify-mongodb"), {
url: "mongodb://localhost:27017/parkedcars"
});
const startFastify = async () => {
try {
await fastify.listen(3333);
fastify.log.info(`server listening on ${fastify.server.address().port}`);
} catch (err) {
fastify.log.error(err);
process.exit(1);
}
};
startFastify();
In my /routes/index.js I have a route...
const carController = require("../controllers/carController");
{
method: "POST",
url: "/api/create/parkedcar",
handler: carController.createParkedCar
}
And finally in my /controllers/carController...
const fastify = require("fastify")();
exports.createParkedCar = async (req, reply) => {
try {
let car = { ...req.body };
const db = fastify.mongo.db
*// will do insert here*
return car;
} catch (err) {
throw boom.boomify(err);
}
};
When I attempt to call:
const db = fastify.mongo.db
I get an error that says...
"Cannot read property 'db' of undefined"
What am I doing wrong here?
How is mongo undefined at this point?
Doesn't "fastify.register" make this accessible to me?
You need to do the require("fastify")() only in your once per application because it is a factory and not a singleton, so every time you run the require you are creating a brand new HTTP server!
The magic is to use the .register in a proper way and/or using function instead of arrow function in the handler.
For your use case you could change the carController:
exports.createParkedCar = function handler (req, reply) {
let car = { ...req.body };
const db = this.mongo.db
*// will do insert here*
db.insert(...)
.then(() => reply.send(car))
.catch((err) => reply.send(boom.boomify(err)))
}
because all the function handlers, in fastify, are bound to the fastify server instance (like this aFunction.bind(fastify)). The arrow functions can't be binded.
Another options is to use the register:
// /routes/index.js
module.exports = (fastify, opts, next) => {
fastify.route({
method: "POST",
url: "/api/create/parkedcar",
handler: async (req, reply) => {
try {
let car = { ...req.body };
const db = fastify.mongo.db
*// will do insert here*
return car;
} catch (err) {
throw boom.boomify(err);
}
});
next() // dont forget it
}
For more info checkout the docs

Display all collections in mongodb+express

This is my code for sending data to a database:
app.post('/thanks', function(req, res) {
if (atendees.checkin === req.body.dbstring) {
dbConn.then(client => {
delete req.body._id;
const db = client.db('mydata')
db.collection(atendees.checkin).insertOne(req.body);
})
(...)
This is how I display on the page after clicking on a href link:
app.get('/view-feedbacks', function(req, res) {
dbConn.then(client => {
const db = client.db('mydata')
db.collection(atendees.checkin).find({}).toArray().then(function(feedbacks) {
res.status(200).json(feedbacks);
atendees.checkin = ' '
}).catch(err => {
throw(err);
})
});
});
That works fine. How can I do something similar to display all collections from the database instead of just the individual ones?
This is what I tried to do:
app.get('/view-history', function(req, res) {
dbConn.then(client => {
const db = client.db('mydata')
db.listCollections().toArray().then(function(collInfos) {
res.status(200).json(collInfos);
atendees.checkin = ' '
}).catch(err => {
throw(err);
})
});
});
But it just gives me the name of each collection. I want to show all collections and all of their elements.
Edit: my question is different from this one: MongoDB Show all contents from all collections .I'm trying to do this on express.js, not on the terminal
Edit2: Using db.collection:
app.get('/view-history', function(req, res) {
dbConn.then(client => {
const db = client.db('mydata')
db.collections().then(function(feedbacks) {
res.status(200).json(feedbacks);
atendees.checkin = ' '
}).catch(err => {
throw(err);
})
});
But this gives the error: TypeError: converting circular structure to JSON
With async/await, this could be done:
app.get('/view-history', async (req, res) => {
try {
const client = await dbConn;
const db = client.db('mydata');
let collections = await db.collections();
let documents = await Promise.all(collections.map(async (collection) => {
let documents = await collection.find({}).toArray();
return Promise.resolve([collection.collectionName, documents]); // Retain collectionName
}));
// Format into an object that looks like `collectionName: documents`
let formatted = documents.reduce((obj, collection) => {
obj[collection[0]] = collection[1];
return obj;
}, {});
res.json(formatted);
} catch (e) {
console.error(e);
res.sendStatus(500);
}
});
A Promise-only approach:
app.get('/view-history', (req, res) => {
dbConn.then((client) => {
const db = client.db('mydata');
return db.collections();
}).then((collections) => {
return Promise.all(collections.map((collection) => {
return new Promise((resolve, reject) => {
collection.find({}).toArray().then((documents) => {
resolve([collection.collectionName, documents]);
}).catch(reject);
});
}));
}).then((documents) => {
let formatted = documents.reduce((obj, collection) => {
obj[collection[0]] = collection[1];
return obj;
}, {});
res.json(formatted);
}).catch((e) => {
console.error(e);
res.sendStatus(500);
});
});
The main reason this code is unnecessarily verbose is because instead of just returning a big array filled with arrays of documents, you probably want an object that retains the name of the collection, like so:
{
collection1: [...documents...],
collection2: [...documents...],
...
}
Instead of:
[
[...documents...],
[...documents...],
...
]
If you do want just a big array of each collection without caring about the names of the collections, it becomes much simpler:
async/await version:
app.get('/view-history', async (req, res) => {
try {
const client = await dbConn;
const db = client.db('mydata');
let collections = await db.collections();
let documents = await Promise.all(collections.map((collection) => collection.find({}).toArray()));
res.json(documents);
} catch (e) {
console.error(e);
res.sendStatus(500);
}
});
Promise-only version:
app.get('/view-history', (req, res) => {
dbConn.then((client) => {
const db = client.db('mydata');
return db.collections();
}).then((collections) => {
return Promise.all(collections.map((collection) => collection.find({}).toArray()));
}).then((documents) => {
res.json(documents);
}).catch((e) => {
console.error(e);
res.sendStatus(500);
});
});
Have you tried just db.collections()? If that also doesn't give what you need, you might have to invoke db.collection(<name>) on each of the names you get from listCollections.

Resources