get request here is just returning an empty array. I cannot figure out why. I've seen others code that looks the exact same work just fine.
I've tried googling the issue but haven't seen relevant answers. I'm using Postman to test it.
const getPantry = async (req, res) => {
const results = await pantry.find({});
return send(res, 200, results)
}
module.exports = cors(
router(
get('/pantry', getPantry),
)
)
I'm expecting a json object but it's just returning the empty array.
The shortest quick and dirty complete working code I can get based on your example is this:
const { send } = require('micro')
const { router, get } = require('microrouter')
const { MongoClient } = require('mongodb')
var pantry = null
MongoClient.connect('mongodb://localhost')
.then(conn => {
pantry = conn.db('test').collection('pantry')
})
const getPantry = async (req, res) => {
const results = await pantry.find({}).toArray();
send(res, 200, results)
}
module.exports = router(get('/pantry', getPantry))
Calling the endpoint using curl:
$ curl 'http://localhost:3000/pantry'
[{"_id":0},{"_id":1},{"_id":2}]
Which correctly shows the content of the collection.
I believe what is missing from your code is the toArray() method. find() by itself returns a cursor and it won't output the query result unless you do something with it, like calling toArray() or iterating on it using forEach()
Related
I'm fetching data from MongoDB, and the response is coming through fine, however it appears to be wrapped in array when it comes out of the User.find() function.
For example, one response is:
[{"_id":"62fe3c888e2776ef3c1a010f","username":"Drago D Trial","password":"U2FsdGVkX1867hs26KL0KitTGhWnP9tdVX6AcmI5pWE=","fullname":"Drago DaTrial","firstname":"","surname":"","email":"drago#hotmail.com","position":"QA Tester","userImage":"","locationCity":"","country":"","role":"","company":"","emailAuthorised":true,"professionalBio":"","positionRecentTitle":"","positionRecentCompany":"","companyAuthorised":"","isAdmin":false,"createdAt":"2022-08-18T13:20:08.045Z","updatedAt":"2022-08-18T13:21:02.619Z","__v":0}]
I'm accessing this through an api like this:
router.get('/inviteToJoinTeam/:token/:email', async (req, res) => {
try {
//verify the token against DB
const userToken = (req.params.token)
const indivEmailAdd = (req.params.email)
// creating user auth
try{
const userDetails = await User.find({email: indivEmailAdd})
const indivIDAdd = await userDetails (!want to access the data here and just get ID)
res.send(indivIDAdd)
}catch{
console.log('failure')
}
} catch (e) {
res.send('This isnt working');
}
});
How would you access this and just get the _id field out?
If there is only one item in the array then - simply get the id property of the first item intthe returned array
const indivIDAdd = await userDetails[0]['_id'];
or using dot notation
const indivIDAdd = await userDetails[0]._id;
if there are multiple results then map over the results and get the id from each
const ids = await userDetails.map(user => user._id);
just use response[0]._id
Ps: Response is the array coming from the database
Try projection for the same it should work
const userDetails = await User.find({ email: indivEmailAdd }, { _id : 1 })
it will return array of ObjectId. if you need to get only one object then use findOne instead of find.
According to me you have 2 solutions :
Option 1 use findOne instead of find :
const userDetails = await User.findOne({email: indivEmailAdd});
Option 2 access array / object with basic js:
const usersDetails = await User.find({email: indivEmailAdd});
const userDetails = usersDetails.at(0)._id; // or
const userDetails = usersDetails[0]['_id'];
Why my Code Giving me Null
async function run() {
try {
await client.connect();
const productsCollection = client.db("inventory").collection("items");
// Get All Products
app.get('/products', async (req, res) => {
const query = {};
const cursor = productsCollection.find(query);
const products = await cursor.toArray();
res.send(products);
});
// Get Single Product
app.get('/products/:id', async (req, res) => {
const id = req.params.id;
console.log(id);
const query = {_id: ObjectId(id)};
const product = await productsCollection.findOne(query);
res.send(product);
})
}
finally {
}
}
run().catch(console.dir);
I do not understand why Null is showing?
And there is no error in giving products /id
And It doesn't even showing anything
And this error is showing in the front end console
Uncaught (in promise) SyntaxError: Unexpected end of JSON input
In mongo, you should use await on every event that is related to the database.
this is because it takes time to actually retrieve the data from the collection
and the javascript code will not wait unless you tell it to.
in your example
const cursor = productsCollection.find(query);
should be
const cursor = await productsCollection.find(query);
this is my first note
My second note is to share your frontend code and I will edit the answer if there is any thing to add
I tried to find the solutions over here but unable to get success while using $pull as the array values I have does not contain `mongo_id'.
So the scenario is that , I am trying to delete the specific comment of the particular user which I am passing through query params. M
My mongo data looks like this:
Now I am making API Delete request like this : http://localhost:8000/api/articles/learn-react/delete-comment?q=1 on my localhost .
ANd finally my code looks like this:
import express from "express";
import bodyParser from "body-parser";
import { MongoClient } from "MongoDB";
const withDB = async (operations, res) => {
try {
const client = await MongoClient.connect(
"mongodb://localhost:27017",
{ useNewUrlParser: true },
{ useUnifiedTopology: true }
);
const db = client.db("my-blog");
await operations(db);
client.close();
} catch (error) {
res.status(500).json({ message: "Error connecting to db", error });
}
};
app.delete("/api/articles/:name/delete-comment", (req, res) => {
const articleName = req.params.name;
const commentIndex = req.query.q;
withDB(async(db) => {
try{
const articleInfo = await db.collection('articles').findOne({name:articleName});
let articleAllComment = articleInfo.comments;
console.log("before =",articleAllComment)
const commentToBeDeleted = articleInfo.comments[commentIndex];
//console.log(commentToBeDeleted)
// articleAllComment.update({
// $pull: { 'comments':{username: commentToBeDeleted.username }}
// });
articleAllComment = articleAllComment.filter( (item) => item != commentToBeDeleted );
await articleAllComment.save();
console.log("after - ",articleAllComment);
//yaha per index chahiye per kaise milega pta nhi?
//articleInfo.comments = gives artcle comment
res.status(200).send(articleAllComment);
}
catch(err)
{
res.status(500).send("Error occurred")
}
},res);
});
I have used the filter function but it is not showing any error in terminal but also getting 500 status at postman.
Unable to figure out the error?
I believe you'll find a good answer here:
https://stackoverflow.com/a/4588909/9951599
Something to consider...
You can use MongoDB's built-in projection methods to simplify your code.
https://docs.mongodb.com/manual/reference/operator/projection/positional/#mongodb-projection-proj.-
By assigning a "unique ID" to each of your comments, you can find/modify the comment quickly using an update command instead of pulling out the comment by order in the array. This is more efficient, and much simpler. Plus, multiple read/writes at once won't interfere with this logic during busy times, ensuring that you're always deleting the right comment.
Solution #1: The recommended way, with atomic operators
Here is how you can let MongoDB pull it for you if you give each of your comments an ID.
await db.collection('articles').updateOne({ name:articleName },
{
$pull:{ "comments.id":commentID }
});
// Or
await db.collection('articles').updateOne({ name:articleName, "comments.id":commentID },
{
$unset:{ "comments.$":0 }
});
Solution #2 - Not recommended
Alternatively, you could remove it by index:
// I'm using "3" here staticly, put the index of your comment there instead.
db.collection('articles').updateOne({ name:articleName }, {
$unset : { "comments.3":0 }
})
I do not know why your filter is erroring, but I would recommend bypassing the filter altogether and try to utilize MongoDB's atomic system for you.
I have the following model in teamMembers.js:
const { Schema, model } = require('mongoose');
const teamMembersSchema = new Schema({
uid: String,
name: String,
hours: Number
})
const TeamMembers = model('teamMembers', TeamMembersSchema);
module.exports = TeamMembers;
I've created the following endpoints in teamMemberRoute.js:
const TeamMembers = require('./models/teamMembers');
module.exports = (app) => {
app.get('/api/pods/teamMembers/:uid', async (req, res) => {
let teamMember = await TeamMembers.find( {'uid': req.params.uid } );
return res.status(200).send(teamMember);
});
app.get('/api/pods/teamMembers', async (req, res) => {
let teamMembers = await TeamMembers.find();
return res.status(200).send(teamMembers);
});
}
The first endpoint (/api/pods/teamMembers/:uid) works just fine - when I pass a uid it returns documents specific to that uid in the TeamMember collection.
The second endpoint should return all documents from the TeamMember collection since no parameters are passed. However, when the request is executed, only [] is returned. We know for a fact that documents exist in the TeamMember collection, since the first endpoint returns data from that collection based on the uid parameter that is passed.
I'm stumped on this. Any ideas? I don't think there is anything wrong with my model since I am able to execute the first endpoint with no issues.
Express executes code from top to button, and that is the reason for this issue. It will match your first endpoint and assume that uid is null. Just change the order of defined endpoints, like this:
module.exports = (app) => {
app.get('/api/pods/teamMembers', async (req, res) => {
let teamMembers = await TeamMembers.find();
return res.status(200).send(teamMembers);
});
app.get('/api/pods/teamMembers/:uid', async (req, res) => {
let teamMember = await TeamMembers.find( {'uid': req.params.uid } );
return res.status(200).send(teamMember);
});
}
I'm trying to return a value out of an array of values I get from querying Datastore.
results[0] have this content: {"prod_name":"Muffin","prod_price":3.99}.
I'd like to return via res.send only: 3.99
I've tried results[0].prod_price, or results[0]['prod_price'], I have tried saving results[0] as variable and trying to return prod_price, but nothing works.
Any help is appreciated.
My code is here:
const Datastore = require('#google-cloud/datastore');
const Storage = require('#google-cloud/storage');
// Instantiates a client
const datastore = Datastore();
const storage = new Storage();
exports.getprice = function getprice (req, res) {
const kind = datastore.createQuery("Dialogflow");
const filter = kind.filter("prod_name", req.body.queryResult.parameters['bakery_items']);
return query = datastore.runQuery(kind)
.then( (results) => {
const entities = results[0];
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ "fulfillmentText": entities}));
})
.catch((err) => {
console.error(err);
res.status(500).send(err);
return Promise.reject(err);
});
};
I got it.
Actually I kept results instead of forcing results[0], and realized the output had an extra array, so to access the value, I had to do: results[0][0]['prod_price']
Thanks to JavaScript console.