How to create a field once in mongoose js - javascript

I am new to mongoose js so i wanted to create a contact feild only one time the user fills a form
here is my contact model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ContactSchema = new Schema({
fname: {
type: String,
required: true,
default:"fname"
},
lname: {
type: String,
required: true,
default:"lname"
},email:{
type:String,
required: true,
default:""
},
mobile:{
type:Number,
required:true,
default:""
},
title:{
type:String,
required:true,
default:""
}
});
module.exports = Contact = mongoose.model('Contact', ContactSchema);
here is my user model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Link Schema
const LinkSchema = require('./Link').schema;
const ContactData=require('./conatct').schema;
// Create User Schema
const UserSchema = new Schema({
username: {
type: String,
required: true,
unique: true,
lowercase:true,
trim: true,
},
email: {
type: String,
required: true,
unique: true,
trim: true,
lowercase:true
},
password: {
type: String,
required: true,
trim: true
},
resetToken:{type:String},
expireToken:{type:Date},
date: {
type: Date,
default: Date.now
},
theme: {
type: Number,
default: 1
},
avatar: {
type: String,
default: 'uploads/default.png'
},
displayname:{
type:String,
default:"",
trim:true
},
bio:{
type: String,
default: "",
},
title:{
type: String,
default: "",
},
links: {
type: [LinkSchema]
},
contact:{
type:[ContactData]
}
});
module.exports = User = mongoose.model('user, UserSchema);
** suggest me some queries for creating contact details only once the user enters the data i have tried from user.contact.push({}) but it creates multiple object in contact array**

If I get you, you want the contact field to be a single object not an array of objects then change
//change
contact:{
type:[ContactData]
}
//to
contact:ContactData
// when you want to add data you just do something like
const user = new User({
name,etc...,
contact.mobile:user_mobile, etc..
})

Related

What is the difference between surrounding the type with square brackets and surrounding the whole object

What is the difference between this code:
const userSchema = new Schema(
{
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
phoneNumber: { type: Number, required: false, unique: true },
address: [{ type: mongoose.Types.ObjectID, required: true, ref: "Address" }],
},
{
timestamps: true,
}
);
And this code:
const userSchema = new Schema(
{
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
phoneNumber: { type: Number, required: false, unique: true },
address: { type: [mongoose.Types.ObjectID], required: true, ref: "Address" },
},
{
timestamps: true,
}
);
NOTICE:
In the first code, I surrounded the whole address object with square brackets.
In the second code, I only surrounded the type property of the address with square brackets.
What I want to know is how that will impact the app's behavior.
Is there any difference?
Thanks.
They both declare an array-of-references, but there are some subtle differences.
Let's take this simple schema:
const userSchema = mongoose.Schema({
address: { type: [ String ], required: true, default: undefined }
});
const User = mongoose.model('User', userSchema);
This will apply the options (required and default) to the address array-of-strings as a whole:
// This will fail validation:
// ValidatorError: Path `address` is required
const doc = new User({});
// This will pass validation:
const doc = new User({ address : [] });
Now change the position of the brackets in the schema:
const userSchema = mongoose.Schema({
address: [{ type: String, required: true, default: undefined }]
});
This will apply the options to the elements of the address array:
// This will pass validation, `address` itself isn't required:
const user = new User({});
// This will also pass validation, for the same reason:
const user = new User({ address : [] });
// This will fail validation, because elements of the array are required to have a proper value
// ValidatorError: Path `address.0` is required
const user = new User({ address : [ '' ] });
EDIT: if you want to enforce that the address field is always defined and has at least one element, you have to use a custom validator. For your schema, it would look like this:
address: {
type: [ mongoose.Schema.Types.ObjectID ],
ref: 'Address',
required: true,
default: undefined,
validate: a => Array.isArray(a) && a.length > 0
}

Student, teacher one common model or two separate ones in mongoose?

I need to create an account for a student and a teacher. Should I create two separate models in mongoose for student and teacher? What's the right approach? Student and teacher will share some properties and some will differ.
At this moment I have only one model for student and tutor:
const userSchema = new Schema({
name: {
type: String,
trim: true,
required: true,
maxLength: 32
},
surname: {
type: String,
trim: true,
required: true,
maxLength: 32
},
email: {
type: String,
unique: true,
trim: true,
required: true,
lowercase: true
},
isActiveTutor: {
type: Boolean,
default: false
},
birthCountry: String,
initials: String,
hashed_password: {
type: String,
required: true
},
salt: String,
role: {
type: String
},
teachingLanguage:{
type: Object,
/*language: {
language,
level,
price
}*/
},
resetPasswordLink: {
data: String,
default: ''
}
}, {timestamps: true});
But what if I wanted to give a teacher properties that a student would not have?
In case someone pass by here.
const options = {discriminatorKey: 'kind'};
const userSchema = new mongoose.Schema({/* user schema: (Common) */}, options);
const User = mongoose.model('User', userSchema);
// Schema that inherits from User
const Teacher = User.discriminator('Teacher',
new mongoose.Schema({/* Schema specific to teacher */}, options));
const Student = User.discriminator('Student',
new mongoose.Schema({/* Schema specific to student */}, options));
const teacher = new Teacher({/* */});
const student = new Student({/* */});
Original answer(modified): here.
Have a look at the docs here.

how to populate users object with field

These the response for user that Im getting from get request to profile API
"user": "5cc3a4e8d37a7259b45c97fe"
What I'm looking for instead is
"user":{
"_id": "5cc3a4e8d37a7259b45c97fe",
"name":"Jhon Doe",
}
Here is my code:
Profile.findOne({
user: req.user.id
})
.populate('user',['name']) // I added this line to populate user object with name
.then(profile=>{
if(!profile){
errors.noprofile = 'There is no profile for this user'
return res.status(404).json(errors);
}
res.json(profile)
})
.catch(err => res.status(404).json(err));
However, Im getting these error:
{
"message": "Schema hasn't been registered for model \"users\".\nUse mongoose.model(name, schema)",
"name": "MissingSchemaError"
}
What am I missing
Profile Schema
const ProfileSchema = new Schema({
user:{
type: Schema.Types.ObjectId,
ref: 'users'
},
handle: {
type: String,
required: true,
max: 40
},
company: {
type: String
},
website: {
type: String,
}
})
Here is how my Users schema looks like
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create Schema
const UserSchema = new Schema({
name:{
type: String,
required: true,
},
email:{
type: String,
required: true,
},
password:{
type: String,
required: true,
},
avator:{
type: String,
},
date:{
type: Date,
default: Date.now,
}
});
module.exports = User = mongoose.model('Users', UserSchema)
Schema that you are referencing in Profile schema is users, but you have saved your user schema as Users. So I would say that you need to update your Profile schema:
const ProfileSchema = new Schema({
user:{
type: Schema.Types.ObjectId,
ref: 'Users'
},
handle: {
type: String,
required: true,
max: 40
},
company: {
type: String
},
website: {
type: String,
}
})
Name under which is saved your User schema can be found in this line
module.exports = User = mongoose.model('Users', UserSchema)
The error says you don't have Schema for Users. You reference it from Profile Schema, but you don't have it. It can be this way:
const Users = new Schema({
name: String
})

How can I save this JSON to a mongoDB database serviced by MonogDB Compass?

I have some raw JSON that I have populated for testing purposes, but now I would like to put it into a mongoDB database using mongoDB Compass.
My mongoDB connection string is working and I have working mongoose code.
How do I go about doing this?
I would hope this would be an easy task as mongoDB stores it's data in the form of BSON already.
Here is a snippet of my code.
const json_string =
`[
{
"link": "https://www.youtube.com/watch?v=BMOjVYgYaG8",
"image": "https://i.imgur.com/Z0yVBpO.png",
"title": "Debunking the paelo diet with Christina Warinner",
// ... snip
},
{ // ... snip
The schema is already created:
// for relevant data from google profile
schema.Article = new Schema({
link: { type: String, required: true },
image: { type: String, required: true },
title: { type: String, required: true },
summary: { type: String, required: true },
tag: { type: String, required: true },
domain: { type: String, required: true },
date: { type: String, required: true },
timestamp: { type: Date, default: Date.now }
});
You can use this
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
mongoose.connect(process.env.MONGO_URI);
const articleSchema = new Schema({
link: { type: String, required: true },
image: { type: String, required: true },
title: { type: String, required: true },
summary: { type: String, required: true },
tag: { type: String, required: true },
domain: { type: String, required: true },
date: { type: String, required: true },
timestamp: { type: Date, default: Date.now }
});
const Article = mongoose.model("Article", articleSchema);
const json_string = `[
{
"link": "https://www.youtube.com/watch?v=BMOjVYgYaG8",
"image": "https://i.imgur.com/Z0yVBpO.png",
"title": "Debunking the paelo diet with Christina Warinner"
}
]`;
const jsonBody = JSON.parse(json_string);
for (let i = 0; i < jsonBody.length; i++) {
const data = jsonBody[i];
const article = new Article({
link: data.link,
image: data.image,
title: data.title
//.... rest
});
article.save();
}
Convert JSON string to an array
Loop through each object in the array
Create a new Article instance based on values from the object
Call the save method on the Article object

Mongodb mongoose node js schema relation

hello i am new on mongodb and node js i have a question
here is my product schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const categorySchema = require('./category');
const ProductSchema = new Schema({
country: {
type: String,
required: [true, "country can't be null"]
},
city: {
type: String,
default: ""
},
name: {
type: String,
required: [true, "name can't be null"]
},
measureValue: {
type: Number,
default: 0
},
minPrice: {
type:Number,
required: [true, "minPrice can't be null"],
min: [1,"minPrice must be at least 1"]
},
maxPrice: {
type:Number,
required: [true, "maxPrice can't be null"],
min: [1,"maxPrice must be at least 1"]
},
photoUrl: {
type:String,
default: ""
},
explanation: {
type: String,
default: ""
},
category: [categorySchema.schema],
userID: {
type: String,
required: [true,"userid cant be null"]
},
isActive: {
type: Boolean,
default: true
},
createdDate: {
type: Date,
default: Date.now
},
deletedDate: {
type:Date
}
})
and here is my category schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const CategorySchema = new Schema({
name: {
type: String,
required: [true, "name can't be null"]
},
createdDate: {
type: Date,
default: Date.now
},
deletedDate: {
type:Date
}
})
i need to do this;
every product data must be have category
if one day,one category's name changed then every product that relation with that category must changed
i am trying to set category id to product schema and when i fetch the data it must be comes every product with category name as json
i am really confused if you help me i'd be really thankful
You can set up your category as :
category: {
type: mongoose.Schema.Types.ObjectId,
ref: 'category' //your model name
}
You can wrap it into an array and name it categories if you want multiple categories.
Then when you get the data, you will have to execute new Product().populate('category') to get retrieve the category data instead of just returning the category ObjectId.

Categories