I am doing FreeCodeCamp's "MongoDB and Mongoose - Create a Model" challenge. I have submitted by code. However, I am getting this error:
Creating an instance from a mongoose schema should succeed
Here are my codes:
let mongoose = require('mongoose')
mongoose.connect(uri, { useNewUrlParser: true, useUnifiedTopology: true });
let personSchema = new mongoose.Schema({
name: {type: String, required: true},
age: Number,
favoriteFoods: [String]
});
let Person = mongoose.model('Person', personSchema);
Have I made any mistake?
Since you are submitting this code to FCC server, you don't need to connect to db by your own. They must be having connections already made to db. You just have to provide the right implementation of Person model. IMO Since you had that line in your submission, code was breaking at that line and subsequent lines were not getting executed. Hence you were getting this error. Creating an instance from a mongoose schema should succeed
Try this -
let mongoose = require('mongoose');
let Schema = mongoose.Schema;
let personSchema = new Schema({
name: {type: String, required: true},
age: Number,
favoriteFoods: [String]
});
let Person = mongoose.model('Person', personSchema);
The following code worked for me after trying many different things suggested on different posts/blogs on the Internet.
require('dotenv').config();
//To-Do # 1: Install & Set up mongoose */
const mongoose = require('mongoose');
mongoose.connect(process.env.MONGO_URI);
//To-Do # 2: Create a Model
const personSchema = new mongoose.Schema({
name: { type: String, required: true },
age: Number,
favoriteFoods: [String]
});
const Person = mongoose.model('Person', personSchema);
I still could not find what was the problem as I tried to copy and paste exactly the code given in the solution to the problem suggested by free code camp and even that did not work. I was using replit and perhaps there must be some problem when the free code camp tests interact with the liver server of replit but some expert should answer the problem in detail to save time for other people.
It appears that the problem occurs because a code below is trying to redeclare the "Person" variable (After making it a const). If you look at the boilerplate code on Replit, there were some codes present there already and part of this code has the following:
let Person;
Simply commenting this line out worked for me.
Related
Before you close this question, I have read several forums that have the same question as I have but my issue is way different. Even when Im not trying to do anything, even save a model, it still gives me an error of:
cannot overwrite "mongoose" model once compiled
I have a feeling there is something wrong with my schemas because when it was still simpler, it worked fine but as I tried to make it more complex it started to give me that error. Here is my mongoose code:
import mongoose from 'mongoose'
const flashcardItemSchema = new mongoose.Schema({
term: {
type:String,
required: true,
min:1
},
description: {
type:String,
required:true,
min:1
}
});
const FlashcardItem = mongoose.model("flashcardItem", flashcardItemSchema);
const flashcardSetSchema = new mongoose.Schema({
title: {
type: String,
min: 1,
},
flashcards:[flashcardItemSchema],
})
const FlashcardSet = mongoose.model('flashcardSet', flashcardSetSchema )
export {FlashcardItem, FlashcardSet}
I connect to my database when the server runs, so it doesn't disconnect from time to time.
UPDATE
I realized that I'm using nextjs builtin api, meaning the api directory is inside the page directory. I only get the error once the pages get recompiled.
So it turns out that the error came from nextjs trying to remake the model every render. There is an answer here: Mongoose/NextJS - Model is not defined / Cannot overwrite model once compiled
but I thought the code was too long and all that fixed mine was just a single line. When trying to save a model in nextjs, it should be written like this:
const modelName = mongoose.models.modelName || mongoose.model('modelName', flashcardSetSchema )
i have created model for the mongo collection like below. but it was giving me the collection output which saved in mongoDB.
var mongoose = require('mongoose'),
Schema = mongoose.Schema({
name: {
type: String
},
age: {
type: Number
},
})
module.exports = mongoose.model('container', Schema);}
But later when i changed the last line of the code which is
"module.exports = mongoose.model('container', Schema);"
to
"module.exports = mongoose.model('container', Schema, 'container');"
it worked properly. I check the mongoose document they say to use the previous line, then why didn't it worked.
your problem seems to be from using "Schema" as a variable name
var ContainerSchema = new mongoose.Schema({
...
});
and exporting
module.exports = mongoose.model("Container", ContainerSchema);
would work.
Ok, im comming from an SQL background and I am just getting my hands dirty using MongoDB and Mongoose.
I have two simple models:
CAR:
let mongoose = require('mongoose');
let carsSchema = new mongoose.Schema({
brand: String,
specfifications: [String],
image: String
});
module.exports = mongoose.model('Car', carSchema);
Driver
let mongoose = require('mongoose');
let Schema = mongoose.Schema;
let driverSchema = new mongoose.Schema({
name: String,
cars: [{ type: Schema.Types.ObjectId, ref: 'Car' }]
});
module.exports = mongoose.model('Driver', driverSchema);
From what I can understand, this seems to be a proper way of handling a one-to-many-relationship where one car can be used by many drivers.
Now I need to add a class called Races which will be used for saving the results for spacific driver in a specific car.
Thinking in SQL I would do something like this:
let mongoose = require('mongoose');
let raceSchema = new mongoose.Schema({
totaltime: String,
laptime: String,
driver: { type: Schema.Types.ObjectId, ref: 'Driver' },
car: { type: Schema.Types.ObjectId, ref: 'Car' }
});
module.exports = mongoose.model('Race', raceSchema);
Would you consider this to be to correct approach in NoSql or am I forcing my SQL-way of thinking into NoSQL?
the answer is it depends
MongoDB or NoSQL theory says if all related data are in one document, then your query will run faster as they will be stored together. So, in most cases we would prefer one single model for both Car and Driver
If you do not query car and drivers together in most of your queries (chances for which would be rare), then what you did is also correct.
Also, MongoDB has a limitation on size of document i.e. 16 MB if you think the cost of storing them together can go beyond 16MB then what you did is correct. However, there is an alternate solution i.e. GridFS which stores the documents into chunks and overcomes this limitation
I'm new to mean and mongodb and was trying to figure out how to populate my answers to my questions. I just changed the words in the platform that I'm learning (examples were posts and comments).
Here's the error message I'm getting.
/Users/joerigby/Documents/codingdojo/full mean/blacktest3/node_modules/express/lib/view.js:62
throw new Error('No default engine was specified and no extension was prov
^
Error: No default engine was specified and no extension was provided.
at new View (/Users/joerigby/Documents/codingdojo/full mean/blacktest3/node_modules/express/lib/view.js:62:11)
at EventEmitter.render (/Users/joerigby/Documents/codingdojo/full mean/blacktest3/node_modules/express/lib/application.js:569:12)
at ServerResponse.render (/Users/joerigby/Documents/codingdojo/full mean/blacktest3/node_modules/express/lib/response.js:961:7)
at /Users/joerigby/Documents/codingdojo/full mean/blacktest3/server/controllers/answers_c.js:53:12
at Query.<anonymous> (/Users/joerigby/Documents/codingdojo/full mean/blacktest3/node_modules/mongoose/lib/query.js:2112:28)
at /Users/joerigby/Documents/codingdojo/full mean/blacktest3/node_modules/mongoose/node_modules/kareem/index.js:177:19
at /Users/joerigby/Documents/codingdojo/full mean/blacktest3/node_modules/mongoose/node_modules/kareem/index.js:109:16
at process._tickCallback (node.js:355:11)
24 Aug 16:48:22 - [nodemon] app crashed - waiting for file changes before starting...
Below are my codes..
from answers_controller.js on server side
show: function(req, res){
console.log(req.params.id);
Question.findOne({_id: req.params.id})
.populate('answers')
.exec(function(err, question) {
res.render('question', {question: question});
});
}
}
from answer model
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectID = require('mongodb').ObjectID;
var AnswerSchema = new mongoose.Schema({
answer: String,
description: String,
likes: {type: Number, default: 0},
created_at: {type: Date, default: Date.now },
_question: {type: Schema.ObjectId, ref: 'Question'}
});
mongoose.model('Answer', AnswerSchema);
from question model
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectID = require('mongodb').ObjectID;
var QuestionSchema = new mongoose.Schema({
title: String,
description: String,
created_at: {type: Date, default: Date.now },
answers: [{type: Schema.Types.ObjectId, ref: 'Answer'}]
});
mongoose.model('Question', QuestionSchema);
Let me know if you need anything else to look at.
Thanks for your time.
The error is not with Mongo or Mongoose. Check the stack trace in your error message. The problem is from res.render. In order to use this method you must either configure express to have a default view engine (ejs, jade, etc.) or provide a file extension after 'question' so that it knows which template file to look for in order to render the HTML.
// in your main server file
// set default view engine
app.set('view engine', 'ejs');
// set view folder (where it looks for the template files
app.set('views', pathToViewFolder);
Now you can create a question.ejs file in the folder at pathToViewFolder.
so I've been at it for like 4 hours, read the documentation several times, and still couldn't figure out my problem. I'm trying to do a simple populate() to my model.
I have a User model and Store model. The User has a favoriteStores array which contains the _id of stores. What I'm looking for is that this array will be populated with the Store details.
user.model
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var UserSchema = new Schema({
username: String,
name: {first: String, last: String},
favoriteStores: [{type: Schema.Types.ObjectId, ref: 'Store'}],
modifiedOn: {type: Date, default: Date.now},
createdOn: Date,
lastLogin: Date
});
UserSchema.statics.getFavoriteStores = function (userId, callback) {
this
.findById(userId)
.populate('favoriteStores')
.exec(function (err, stores) {
callback(err, stores);
});
}
And another file:
store.model
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var StoreSchema = new Schema({
name: String,
route: String,
tagline: String,
logo: String
});
module.exports = mongoose.model('Store', StoreSchema);
After running this what I get is:
{
"_id": "556dc40b44f14c0c252c5604",
"username": "adiv.rulez",
"__v": 0,
"modifiedOn": "2015-06-02T14:56:11.074Z",
"favoriteStores": [],
"name": {
"first": "Adiv",
"last": "Ohayon"
}
}
The favoriteStores is empty, even though when I just do a get of the stores without the populate it does display the _id of the store.
Any help is greatly appreciated! Thanks ;)
UPDATE
After using the deepPopulate plugin it magically fixed it. I guess the problem was with the nesting of the userSchema. Still not sure what the problem was exactly, but at least it's fixed.
I think this issue happens when schemas are defined across multiple files. To solve this, try call populate this way:
.populate({path: 'favoriteStores', model: 'Store'})