I'm currently creating a MEAN application to allow a user to create a football team from a list of ownedPlayers. Currently however when I attempt to make a http.get call to the ownedPlayers collection in MongoDB it always returns an empty array.
My mongoose model for OwnedPlayers is as follows.
var OwnedPlayers = mongoose.model('OwnedPlayers', {
userid: String,
playerid: String,
position: String
});
The endpoint and query is as follows.
app.get('/api/ownedPlayers', function (req, res) {
console.log('userid used in request', req.query.userid)
console.log('position used in request', req.query.position)
OwnedPlayers.find({
userid: req.query.userid, position: req.query.position
}, function (err, owned)
{
if (err)
{
res.send(err);
}
console.log('owned',owned);
res.json(owned);
});
});
I can confirm that the values in req.query.userid and req.query.position do match a single record in my ownedPlayers collection. This can be seen by my nodejs output below.
App listening on port 8080
GET /api/teams/57f50267418cb72fd020196a 304 31.936 ms - -
userid used in request 57f50267418cb72fd020196a
position used in request goal
owned []
GET /api/ownedPlayers?userid=57f50267418cb72fd020196a&position=goal 304 32.903 ms - -
I can also confirm that the key names are correct as userid and position.
The document I would expect to be returned when userid = 57f50267418cb72fd020196a and position = position= goal is as follows.
_id:57f7717ab1f0f22f3c3950b9
userid:57f50267418cb72fd020196a
playerid:57f7797e00ea2a0dc8609701
position:goal
Any help would be much appreciated as I'm very new to mongodb and mean applications.
Thanks in advance.
The problem was that since I was using an collection with documents which weren't created via mongoose it wasn't finding the collection correctly.
By passing in the collection name as a third parameter when creating my models this explicitly sets the collection name and points mongoose in the right direction.
Related
I am using Nodejs and MongoDB. This is my data:
[{Id:1234
Name:someone,
Email: someone#gmail.com},
{Id:4321
Name:john,
Email: john#gmail.com},
{Id:6789
Name:sarah,
Email: sarah#gmail.com}]
I want to get all the values of the name field and send it as a response to the frontend. I tried using find.project and some other methods but it keeps on returning a null array.
I'm new at Mongoose and Nodejs so that's why I'm not sure how this is supposed to be done.
Try this:
Model.find({}, {name: 1, _id: 0}, (error, data) => {
if (!error) {
// send data in your response.
}
});
Note: Here Model is your mongoose db model.
Query the collection using the following code inside the GET route,
Collection.find({})
.then(users=>{ // users variable stores all records fetched from the database
res.render("usersHTML",{users}); // "usersHTML" is the ejs file
}) // users data are passed to the ejs file
.catch(err=>{console.log(err)});
Now as the users records are passed to the frontend just use a loop to traverse the users and get the names of each record using users[i].name.
I am attempting a CRUD app with MEAN stack. I am using mongoose in Express to call to the MongoDB. I am using the FindOne function with a specified parameter, and it's always returning the same (incorrect) document.
I know I am connected to the correct database, since I get a document back from that collection, but it's always the same document, no matter what I pass as the parameter.
module.exports = mongoose.model('Player', playersSchema, 'players'); //in player.js
const Player = require('./model/players');
app.get('/api/player/:id', (req, res) =>{
Player.findOne({id: req.params.playerId},
function(err, player) {
if(err) {
res.json(err);
}
else {
res.json(player);
}
});
});
I have 3 separate "players", with three distinct "playerID" fields (38187361, 35167321, 95821442). I can use Postman to GET the following URL, for example:
http://localhost:3000/api/player/anythingyouWantInHere
and it will return 38187361, the first document. I've been over this website, many tutorials, and the Mongoose documentation and I can't see what I'm doing wrong..
I'd like to eventually find by playerId OR username OR email, but one hurdle at a time...
From the mongoose documentation of findOne, if you pass Id a null or an empty value, it will query db.players.findOne({}) internally which will return first document of the collection everytime you fetch. So make sure you are passing non-empty id here.
Note: conditions is optional, and if conditions is null or undefined,
mongoose will send an empty findOne command to MongoDB, which will
return an arbitrary document. If you're querying by _id, use
findById() instead.
Your route is '/api/player/:id', so the key on the req.params object will be 'id' not 'playerId'.
I don't know what/where/if you're populating the playerId param, but if you update your query to call req.params.id it should actually change the document based on the path as you seem to be wanting to do.
I had the same problem, and it was that the name of column's table was different from the model I had created.
In my model the name of the wrong column was "role" and in my table it was "rol".
Basically I'm trying to find a way in which to find a way to plug req.params.name into a find() query.
I have tried:
Trying to pass through my req.params variable in my find() object parameter Card.find({cardName: req.params.name}, callback) and any other possible variance of that.
I've tried a static method for findByName in which I just did Card.findByName(req.params.name, callback);
When I do console.lo(req.params.name) it returns the name of the card; however, when I got to show.ejs I do console.log(cardstatsok.cardName) it comes back undefined.
I've searched here on Stack Overflow, I've checked my Udemy message board, and I've tried finding any tutorial on passing route parameters to a find query, and alas, nothing.
Here's my code:
My schema and model:
var cardSchema = new mongoose.Schema({
cardName: String,
id: Number,
cardSet: String,
image: String,
ability: String
});
var Card = mongoose.model("Card", cardSchema);
My route for my single card page:
app.get("/cards/:name", function(req, res) {
Card.find({"cardName":req.params.name}, function(err, cardInfo){
if(err){
res.redirect("/cards");
console.log(err);
} else {
res.render("show", {cardstatsok: cardInfo});
}
});
});
When I do console.log(cardInfo) it returns many objects since I used "Forest" and the copy of the Magic: The Gathering card Forest has been printed many times. Here's one, though:
{ _id: 5a85bb554c8fff0c04f15b8e,
cardName: 'Forest',
id: 243461,
cardSet: 'Duel Decks: Knights vs. Dragons',
image: 'http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=243461&type=card',
__v: 0 }
find() returns an array which means cardstatsok is an array.
So console.log(cardstatsok.cardName) won't work. Use console.log(cardstatsok[0].cardName) instead for the first card or console.log(cardstatsok) for everything. If you want to print all the card names you have to loop over the array.
To find only one card you can use findOne() instead.
I am running into following error but I unable to completely grasp the understanding behind the error.
CastError: Cast to ObjectId failed for value "XYZ" at path "_id" for model "Partner"
I have my schema defined as following
var partnerList = new Schema (
{
partnerName: String,
supportedProducts: [String]
},
{
collection: 'partnerList'
}
);
module.exports = mongoose.model('Partner', partnerList);
The functionality of my delete function
delete: function (req, res) {
var removePartner = req.params.partnerName;
var promise = Partner.findByIdAndRemove(removePartner).exec();
promise.then(function removePartner(val) {
console.log('partner value removed');
res.send(val);
}).catch(function catchError(err){
console.error(err);
throw err;
});
}
I am trying to making a request to my node app service using
localhost:8443/data/XYZ, where i am passing the value 'XYZ' as the parameter. This value is used to delete the appropriate object from the database.
Basically the error means that whatever you pass as your "XYZ" url param is not a valid ObjectId.
Guessing from your code you use the "partner name" (probably some arbitrary string) instead of the database id of the partner. However findByIdAndRemove() requires you to specify an ObjectId as it uses this to identify which document to delete:
Model.findByIdAndRemove(id, [options], [callback])
Your delete API call could then look something like this: http://localhost:8443/data/59558ccd7acc4dd63ea88988. However for this the client needs to know the ObjectId of the partner.
So you have to either use the ObjectId of a partner in the URL, or use remove() to implement your custom delete query instead, for example like this (if name is the property you use to store your partner names):
Partner.remove({ name: partnerName }).exec();
Be careful however that this might remove multiple documents if your partner name is not unique, as remove will delete all documents matching the query.
In order to prevent this you can also use findOneAndRemove() using the same query. This would only remove one document at a time. If there are multiple partners with the same name it would remove the first one (depending on your sort order).
Is it possible to query a returned collection in mongoose for mongodb. So in the example below I wish to return to the page the full list of steps, as well as the currentStep. The line I am unsure about is currentStep: steps.?????(page).
Thanks
var page = (req.params.page == undefined?1:req.params.page)
db.stepModel.find().sort({number:1}).exec(function(err, steps) {
if (err) { return next(err); }
res.render('scheme', {
title: 'Fnol',
user: req.user,
steps:steps,
currentStep: steps.?????(page),
page:page
});
};
You can use steps as an array:
currentStep : steps[page - 1].toObject()
The - 1 is because it seems that you use 1-based indexing for the page, whereas arrays are 0-based.
The toObject() converts the Mongoose result into a proper JS object, so you can access properties like _id from within your template.