I'm working through a mongoDB tutorial, and the instructor suggests I use the following code to validate the entry of a user into my database. I have already defined a User model, which just accepts a name, and looks like this:
it("Can create a subdocument", (done) => {
const joe = new User({
name: "joe",
});
joe.save()
.then(() => User.findOne({ name: "joe"}))
.then((user) => {
assert(user.name === "joe")
done();
});
}
However, I don't understand why using the User.findOne function is necessary here. Why can't we just use:
joe.save().then((user) => {
assert(user.name === "joe")
done();
});
Thanks for your help!
If you want to validate the entry, means you need to make sure that the data is really inserted correctly on the db. How to do this is, after saving, you need to find the data directly to the db using findOne, then you validate that data you are getting, is that match with the one you intended to insert
Related
How do you make a relationship in firebase and use the fields? I'm picking up here. I'm working with firestore here and I made relationships like this:
Where I have the collection of answers and it has serviceId collaboratorId and tokenId each of these there is a foreign key of the other collections that you can see in the image. I don't know if this is right, but assuming it's right anyway, how do you use this in React? When it was all string I could add it, now that it's changed to a reference it doesn't work anymore :(
To add I was doing this:
async function handleSubmitResult(e) {
e.preventDefault();
await createFormSchema
.validate({
name,
service,
collaborator,
})
.then(() => {
addDoc(answersCollectionRef, {
name,
service,
collaborator,
answer1,
answer2,
answer3,
answer4,
comment,
createdAt: new Date().toString(),
});
console.log("SALVO NO FIREBASE! 🔥");
// A temporary fix to clear fields of the form
document.getElementById("form-rating").reset();
setName("");
setService("");
setCollaborator("");
setAnswer1(0);
setAnswer2(0);
setAnswer3(0);
setAnswer4(0);
setComment("");
navigate("/thanks");
})
.catch((error) => {
toast.error(error.message, {
theme: "colored",
});
});
}
This works perfectly when it was a string, but now that the fields have changed to the references of the collections I mentioned, I can no longer save it the way I want it in the firestore.
---- After edit my question ------
And when I edit my save method to:
async function handleSubmitResult(e) {
e.preventDefault();
await createFormSchema
.validate({
name,
service,
collaborator,
})
.then(() => {
addDoc(answersCollectionRef, {
name,
serviceId: service,
collaboratorId: collaborator,
answer1,
answer2,
answer3,
answer4,
comment,
createdAt: new Date().toString(),
tokenId: token,
});
console.log("SALVO NO FIREBASE! 🔥");
// A temporary fix to clear fields of the form
document.getElementById("form-rating").reset();
setName("");
setService("");
setCollaborator("");
setAnswer1(0);
setAnswer2(0);
setAnswer3(0);
setAnswer4(0);
setComment("");
navigate("/thanks");
})
.catch((error) => {
toast.error(error.message, {
theme: "colored",
});
});
}
It doesn't show any errors, it now is saving, but it saves as a string. Wouldn't it be correct to save the ID, given that I'm doing a one-to-many relationship? That's what I can't understand...
My firebase looks like this after saving:
------ Add ID of the document Service
Here is my Service, how get id document?
If you want to store a reference to another document in the database, make sure that the value you pass in your code is a DocumentReference object to that document.
E.g. say that you want the name field to be a DocumentReference to the Users collection, that'd be something like:
addDoc(answersCollectionRef, {
name: new DocumentReference(db, "Users", "idOfUserDocument"),
...
});
i am developing a todolist application so that for each user i store the activities of a user in an array. schema of user look like this.
const activitySchema=new mongoose.Schema({
activity:String
})
const Activity=new mongoose.model("activity",activitySchema)
const userSchema=new mongoose.Schema({
username:String,
password:String,
activities:[],
});
i used pull command to delete a specific activity from user actvities list
app.post("/delete",(req,res)=>{
User.updateOne( {username: req.user.username}, { $pull: { activities: { _id: req.body.activity} }
}, function(err, model){
if(err)
console.log(err);
else {
console.log(model)
res.redirect("/")
}
})
})
this code is working after user clicks for 5-10 times on delete button but not immediately. the log output showing matched document:1 and modified document:0. kindly assist
For Modifying the document you need to save the model after making every change to the model.
activity.save().then(()=>{ console.log("Document Saved"))
Similar is the for the other document where you are making a change, You can read more about it if you want Mongoose
I'm currently learning MongoDB using mongoose and nodeJS. I'm trying to store notes to a database called 'notes'. For this, first I connected to the database like this:
mongoose.connect(`mongodb+srv://pedro_yanez:${password}#fsopen-2021-project.ngteq.mongodb.net/note-app?retryWrites=true&w=majority`,
{
useNewUrlParser: true,
useUnifiedTopology: true,
})
Then, I created a Note Schema and a Note Model:
const noteSchema = new mongoose.Schema({
content: String,
date: Date,
important: Boolean
})
const Note = mongoose.model('Note', noteSchema)
Then, I saved three documents to the database:
const note = new Note({
content: 'Note #N',
date: new Date(),
important: true
})
note.save().then(result => {
console.log('note saved!')
mongoose.connection.close()
})
This was successfull as I can see them on MongoDB Atlas' collections, but when I try to query the uploaded notes using mongoose's find() method the following way:
Note.find({}).then(result => {
result.forEach(note => {
console.log(note)
})
mongoose.connection.close()
})
I get the following error:
node_modules/mongoose/lib/query.js:2151
return cursor.toArray(cb);
^
TypeError: cursor.toArray is not a function
Note that the code that I attached is from HY's 'Full Stack Open 2021' course, from part3.c.
I also tried to use find() with a callback function as stated here:
Note.find({}, function (err, docs) {console.log(docs)});
mongoose.connection.close()
But I get 'undefined' and another error:
/node_modules/mongodb/lib/collection.js:238
throw new error_1.MongoInvalidArgumentError('Method "collection.find()" accepts at most two arguments');
^
MongoInvalidArgumentError: Method "collection.find()" accepts at most two arguments
I could really use a hint on what's wrong with my implementation, as I've been fighting with this all day!
I see we are in the same exercise on Fullstack open.
I managed to log all "notes" following the quick start from https://mongoosejs.com/
After mongoose.connect:
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
// Here I used the Model.find() at the end of the page and closed
// the connection as they say in the lesson.
});
It worked here, hope it helps.
I want to do something like this in the firestore
const sendwant = (f) => {
fire
.firestore()
.collection("Rooms")
.doc(f.roomname)
.collection("wants")
.doc()
.where("user","!=",f.displayName)
.set({
user: user.displayName,
status: false,
roomname: f.roomname,
created: f.user,
date: firebase.firestore.FieldValue.serverTimestamp(),
})
.then(() => {
alert("You sent a request to join this room wait for an answer");
});
};
Since I don't want multiple same users in the collection, I want this operation to run when the user value is not equal to the displayName value. If you know another way please help me
This never will give any results:
.collection("wants")
.doc()
.where("user","!=",f.displayName)
The doc() call in here creates a reference to a new, non-existing, unique document. And you when filter that for only documents with a specific condition.
If you want all documents from wants with a different display name, that'd be:
.collection("wants")
.where("user","!=",f.displayName)
EDIT: Since I wasn't able to find a correct solution, I changed the
application's structure a bit and posted another question:
Mongoose - find documents not in a list
I have a MEAN app with three models: User, Task, and for keeping track of which task is assigned to which user I have UserTask, which looks like this:
const mongoose = require("mongoose");
const autopopulate = require("mongoose-autopopulate");
const UserTaskSchema = mongoose.Schema({
completed: { type: Boolean, default: false },
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
autopopulate: true
},
taskId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Task",
autopopulate: true
}
});
UserTaskSchema.plugin(autopopulate);
module.exports = mongoose.model("UserTask", UserTaskSchema);
In my frontend app I have AngularJS services and I already have functions for getting all users, all tasks, and tasks which are assigned to a particular user (by getting all UserTasks with given userId. For example:
// user-task.service.js
function getAllUserTasksForUser(userId) {
return $http
.get("http://localhost:3333/userTasks/byUserId/" + userId)
.then(function(response) {
return response.data;
});
}
// task-service.js
function getAllTasks() {
return $http.get("http://localhost:3333/tasks").then(function(response) {
return response.data;
});
}
Then I'm using this data in my controllers like this:
userTaskService
.getAllUserTasksForUser($routeParams.id)
.then(data => (vm.userTasks = data));
...and because of autopopulate plugin I have complete User and Task objects inside the UserTasks that I get. So far, so good.
Now I need to get all Tasks which are not assigned to a particular User. I guess I should first get all Tasks, then all UserTasks for a given userId, and then make some kind of difference, with some "where-not-in" kind of filter.
I'm still a newbie for all the MEAN components, I'm not familiar with all those then()s and promises and stuff... and I'm really not sure how to do this. I tried using multiple then()s but with no success. Can anyone give me a hint?
You can do at server/API side that will more efficient.
In client side, if you want to do then try below
var userid = $routeParams.id;
userTaskService
.getAllTasks()
.then((data) => {
vm.userTasks = data.filter(task => task.userId !== userid)
});