It looks like it doesn't like how I set the nested schema?
User Schema
const mongoose = require("mongoose");
const twitchSchema = mongoose.Schema(
{
id: Number,
login: String,
display_name: String,
type: String,
broadcaster_type: String,
description: String,
profile_image_url: String,
offline_image_url: String,
view_count: Number,
email: String,
created_at: String,
provider: String,
accessToken: String,
refreshToken: String,
},
{ _id: false }
);
const userSchema = new mongoose.Schema({
provider: {
youtube: {},
twitch: twitchSchema,
},
});
module.exports = mongoose.model("User", userSchema);
This is how I create a new document
const userModels = new UserModels();
userModels.provider[profile.provider].login = profile.login;
const result = await userModels.save()
You should always add the error you are getting in your question. I have tried your code and got undefined reference error:
// Schema setup
const mongoose = require('mongoose');
const twitchSchema = mongoose.Schema(
{
id: Number,
login: String,
display_name: String,
type: String,
broadcaster_type: String,
description: String,
profile_image_url: String,
offline_image_url: String,
view_count: Number,
email: String,
created_at: String,
provider: String,
accessToken: String,
refreshToken: String,
},
{ _id: false }
);
const userSchema = new mongoose.Schema({
provider: {
youtube: {},
twitch: twitchSchema,
},
});
module.export = mongoose.model('User', userSchema);
// Driver code
const u = new User();
console.log(u);
const profile = {
provider: 'twitch',
login: 'dummy_login',
};
u.provider[profile.provider].login = profile.login;
console.log(u);
const res = await User.create(u);
console.info(res);
// Error
// { _id: new ObjectId("624e8901dc46c217a1461c41") }
// TypeError: Cannot set property 'login' of undefined
So the problem is while setting the login field in the user model. You should tweak your userSchema like this:
const userSchema = new mongoose.Schema({
provider: {
youtube: {},
twitch: { type: twitchSchema, default: {} },
},
});
Please see mongoose documentation here.
Now if you run the below driver code it is able to create the record in mongo.
const u = new User();
console.log(u);
const profile = {
provider: 'twitch',
login: 'dummy_login',
};
u.provider[profile.provider].login = profile.login;
console.log(u);
const res = await User.create(u);
console.info(res);
See logs below:
{ _id: new ObjectId("624e8a9990d90dea47e7f62a") }
{
provider: { twitch: { login: 'dummy_login' } },
_id: new ObjectId("624e8a9990d90dea47e7f62a")
}
{
provider: { twitch: { login: 'dummy_login' } },
_id: new ObjectId("624e8a9990d90dea47e7f62a"),
__v: 0
}
Try defining user schema like this :-
const userSchema = new mongoose.Schema({
provider: {
youtube: {},
twitch: [twitchSchema],
},
});
You are using mongoose.Schema incorrect. This is called embeded documents in mongodb. You can define schema like following:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const twitchSchema = new Schema({
id: Number,
login: String,
display_name: String,
type: String,
broadcaster_type: String,
description: String,
profile_image_url: String,
offline_image_url: String,
view_count: Number,
email: String,
created_at: String,
provider: String,
accessToken: String,
refreshToken: String,
});
const userSchema = new Schema({
provider: {
youtube: {},
twitch: [twitchSchema],
},
});
module.exports = mongoose.model("User", userSchema);
There are a couple issues:
your schema definition has extra commas, missing 'new', and curly brackets, and an additional _id object just hanging out there.
youtube: {}, is not a valid schema type, should be youtube: Object for example, or define a schema for it! (see my next bullet)
You can't nest one schema within another like this, see comment from Bhaskar. I'd suggest you define TwitchSchema and a YoutubeSchema separately, and combine them in a third UserSchema.
If you omit fields at doc creation ( only provide 'login' and omit others) the resulting document WILL NOT have any other fields. If that is not what you want, provide at least default empty values for all other fields as well.
const mongoose = require('mongoose');
main().catch(err => console.log(err));
async function main() {
await mongoose.connect('mongodb+srv://ADDYOURS'); // <--- add url
const TwitchSchema = new mongoose.Schema({
id: Number,
login: String,
display_name: String,
type: String,
broadcaster_type: String,
description: String,
profile_image_url: String,
offline_image_url: String,
view_count: Number,
email: String,
created_at: String,
provider: String,
accessToken: String,
refreshToken: String
});
const YoutubeSchema = new mongoose.Schema({
id: Number,
login: String
});
const userSchema = new mongoose.Schema({
id: Number,
twitch : [TwitchSchema],
youtube : [YoutubeSchema]
});
UserModels = mongoose.model("User", userSchema);
const UserDocument = new UserModels();
let profile = {
provider : 'twitch',
login : 'foobars'
}
UserDocument[profile.provider].push({ login : profile.login});
console.log( UserDocument[profile.provider]);
const result = await UserDocument.save()
}
The above results in the following document:
If I were you I would do something like this
Define Schemas
const TwitchSchema = new mongoose.Schema({
twitchID: Number,
login: String,
display_name: String,
type: String,
broadcaster_type: String,
description: String,
profile_image_url: String,
offline_image_url: String,
view_count: Number,
email: String,
created_at: String,
provider: String,
accessToken: String,
refreshToken: String
});
const YoutubeSchema = new mongoose.Schema({
youtubeID: Number,
login: String
});
const UserSchema = new mongoose.Schema({
twitch: {
type: Schema.Types.ObjectId,
ref: 'Twitch'
},
youtube: {
type: Schema.Types.ObjectId,
ref: 'Youtube'
}
});
const User = mongoose.model('User', UserSchema);
const Twitch = mongoose.model('Twitch', TwitchSchema);
const Youtube = mongoose.model('Youtube', YoutubeSchema);
After this when I want to save the user and twitch value. I would do
route.post('/fake-route', async (req, res) => {
try {
//let's assume I have all the value from twitch in the `twitchData` variable
let twitchData = getTwitchData();
// Save Twitch Data to Mongo
const twitchSaveToDB = await Twitch.create(twitchData);
//Now Save User data using above saved Twitch Data
let userDataToSave = {
twitch: twitchSaveToDB._id
};
const userToDB = await User.create(userDataToSave);
res.status(201).json({
message: 'User Created'
});
} catch (err) {
console.error(err);
res.status(500).json({
message: 'Error Occured'
});
}
})
I didn't test the code exactly, so there might be few things to fix here and there but this would be the general concept I would follow
I'm want to join collection mongoDB but I've 2 model in project.
ADMINDETAIL and ADMINDETAIL get UID from member.model.js .
How I populate that.
queue.model.js
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var queueSchema = Schema(
{
QUEUE: String,
UID: String,
DATETIME: String,
ADMIN_ID: String,
USERDETAIL:{
type: Schema.Types.String,
ref:"MEMBER"
},
ADMINDETAIL:{
type: Schema.Types.String,
ref:"MEMBER"
},
},
{
collection: "QUEUE"
}
);
var QUEUE = mongoose.model("QUEUE", queueSchema);
module.exports = QUEUE;
member.model.js
var mongoose = require("mongoose");
var memberSchema = mongoose.Schema(
{
UID: {type: String},
NAME: {type: String},
SURNAME: {type: String},
IDNUMBER: {type: String},
PHONE: {type: String},
ADDRESS: {type: String},
},
{
collection: "MEMBER"
}
);
var MEMBER = mongoose.model("MEMBER", memberSchema);
module.exports = MEMBER;
queue.router.js
// GET QUEUE BY USER
router.get("/byuid/:UID", (req, res) => {
var {UID} = req.params;
Queue.find({UID})
.populate({Path:"USERDETAIL",model:"MEMBER"})
.populate({Path:"ADMINDETAIL",model:"MEMBER"})
.exec((err, data) => {
if (err) return res.status(400).send(err);
return res.status(200).send(data);
});
});
Error I got.
TypeError: utils.populate: invalid path. Expected string. Got typeof `object`
change the type of filed from String to ObjectId like this:
USERDETAIL:{
type: Schema.Types.ObjectId ,
ref:"MEMBER"
},
ADMINDETAIL:{
type: Schema.Types.ObjectId ,
ref:"MEMBER"
},
},
add your new data after that you can like this for population:
.populate("USERDETAIL ADMINDETAIL")
or
.populate([{
path: 'USERDETAIL ',
model: 'MEMBER'
}, {
path: 'ADMINDETAIL',
model: 'MEMBER'
}])
I think you are missing []
I've a schema in Mongo like below:
({
title: String,
genre: String,
publishDate: Date,
index:Number,
requirementInformation:{
requirementInformationStatus:{
type: String,
required: true
},
requirement: [{ requirementId: {
type: Number
},requirementState: {
type: String
}}]
}
})
I want to Auto-increment the field requirementId in Node.js. I tried using mongoose-auto-increment package but not able to create the Auto-increment for the nested Object. Need some help.
My code is as below:
const mongoose = require('mongoose')
const Schema= mongoose.Schema;
var autoIncrement = require('mongoose-auto-increment');
var connection = mongoose.createConnection("mongodb://localhost/Test");
autoIncrement.initialize(connection);
var bookSchema = new Schema({
title: String,
genre: String,
publishDate: Date,
index:Number,
requirementInformation:{
requirementInformationStatus:{
type: String,
required: true
},
requirement: [{ requirementId: {
type: Number
},requirementState: {
type: String
}}]
}
});
bookSchema.plugin(autoIncrement.plugin, {model:'Book',field: 'requirementInformation.requirement.requirementId'});
//authorSchema.plugin(autoIncrement.plugin, 'Author');
var Book = connection.model("Book", bookSchema);
const me = new Book({
title: 'MyBook',
requirementInformation:{requirementInformationStatus:'True',requirement:[{requirementState:"hj"}]}
})
me.save().then(() => {
console.log(me)
}).catch((error) => { console.log(error) })
How can I access the requirementId field?
I want to set a char datatype in nodejs model if it is possible. I try to my best for find that solution.
If not possible than please give me another way for doing it.
Thank you
show error
char is not defined
model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const AdminSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: Char,
required: true
},
skype_id: {
type: String
},
password: {
type: String,
required: true
}
});
Use a String type with a maxlength of 1:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const AdminSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
maxlength: 1
},
skype_id: {
type: String
},
password: {
type: String,
required: true
}
});
More info on this can be found in the docs.
Here, some example datatype for you.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const AdminSchema = new Schema({
name: {
type: String, // String Format
required: true // If required
},
first_name: {
type: String // String format, but not required
},
favorite_number: {
type: Number, // Number format
get: v => Math.round( v ),
set: v => Math.round( v ),
alias: 'i'
},
... // etc
});
I`m trying create ref from one collection to another collection but not with ref on id.
For example: I have two schema, user and foo. Foo has one unique property 'name'.
USER
const mongoose = require('mongoose');
const userSchema = mongoose.Schema({
username: {
type: String,
require: true
},
foo: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Foo'
}
});
mongoose.model('User', userSchema);
FOO
const mongoose = require('mongoose');
const fooSchema = mongoose.Schema({
name: {
type: String,
require: true,
index: {
unique: true
}
}
});
mongoose.model('Foo', fooSchema);
This is work perfect, but can I do ref on that unique property (not on _id)? Like this:
const userSchema = mongoose.Schema({
username: {
type: String,
require: true
},
foo: {
type: String,
property: 'name',
ref: 'Foo'
}
});
Thanks for any answers ;)