ReferenceError Articles is not defined - node.js

I have several schemas defined. Here's one that works fine:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var NewsSchema = new Schema({
name: String,
route: String,
remoteURL: String,
articles: [{title: String, link: String, Image: String, contentSnippet: String}],
retrieved: Date,
dormant: { type: Boolean, default: false}
});
module.exports = mongoose.model('News', NewsSchema);
Here's a second one that's nearly identical:
var mongoose = require('mongoose'),
Schema = mongoose.Schema
// NewsSchema = new Schema({ name: String });
var ArticlesSchema = new Schema({
title: String,
link: String,
pubDate: Date,
image: String,
contentSnippet: String,
sourceName: String
// sourceId: [ {type: Schema.Types.ObjectId, ref: NewsSchema}]
});
module.exports = mongoose.model('Articles', ArticlesSchema);
I've loaded both of the modules at the top of my program, along with a bunch of other stuff like this:
players = require('./app/models/players'),
articles = require('./app/models/articles'),
If I create an instance of the first one with something like:
var player = new Players();
But if I try to create an instance of the second one with:
var item = new Articles();
I receive the error in the subject. In tracing the code I can see that the modules are in scope, so I don't believe it's something stupid like redefining a variable or something like that.
There are several questions of this nature posted here and none of the accepted answers apply.
Any ideas?

Well, upon further analysis, the working "model" no longer worked. It turns out that I had altered the case in the require statements at the top based on suggestions from Visual Studio Code. All is well now.

instead of
sourceId: [ {type: Schema.Types.ObjectId, ref: NewsSchema}]
use
sourceId: [ {type: Schema.Types.ObjectId, ref: 'NewsSchema'}]
would solve your problem

Related

Error when using _id as a property type in a Mongoose Schema

I am learning MongoDB and mongoose at the moment. I have a Archive and a User schema in mongoose:
archive.js
var mongoose = require('mongoose');
var User = require('../users/user');
var notesSchema = new mongoose.Schema({
author: User.userId,
text: String,
files:[String]
});
var archiveSchema = new mongoose.Schema({
name: String,
priority: String,
deadline: Date,
status: String,
assigned_memnbers: [User.userId],
notes: [notesSchema],
});
archiveSchema.virtual('archiveId').get(function() {
return this._id;
});
module.exports = mongoose.model('Archive', archiveSchema);
user.js:
var mongoose = require('mongoose');
var userSchema = new mongoose.Schema({
username: String,
mail: String,
bio: String,
password: String
});
userSchema.virtual('userId').get(function() {
return this._id;
});
module.exports = mongoose.model('User', userSchema);
When I run my server i get the error
TypeError: Invalid value for schema path `author`, got value "undefined"
The the problem comes from author: User.userId, but I don't know how to make a reference between the two tables.
For reference, here is what my complete db design more or less looks like:
Any input on how to solve this problem or improve the overall design is welcome. Thanks you.
I think what you're talking about is a reference to other collection:
author: { type: Schema.Types.ObjectId, ref: 'User' }
and
assigned_members: [{ type: Schema.Types.ObjectId, ref: 'User' }]
should work fine.
Source: Mongoose population
I faced the same issue.I had imported a module, It was just not exporting from another module. so I have added:
exports.genreSchema = genreSchema;

Why is module returning a blank object most of the time?

I am trying to figure out why my module isn't loading properly. It's a mongoose model, but even having it just return a string sometimes returns the empty object, so it seems like it's something to do with node.
articles/models/articles.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var articleSchema = new Schema({
title: String,
slug: String,
author: { type: mongoose.Schema.ObjectId, required: true},
likes: {type: Number, default: 0},
comments: {type: Number, default: 0},
outro: String,
metadescription: String,
metaimage: String,
},{timestamps: true});
//queries
articleSchema.statics.new = require('../queries/new.js');
articleSchema.statics.get = require('../queries/get.js');
articleSchema.statics.single = require('../queries/single.js');
articleSchema.statics.update = require('../queries/update.js');
articleSchema.statics.delete = require('../queries/delete.js');
//articleSchema.statics.updateCommentCount = require('../queries/updateCommentCount.js');
var model = mongoose.model('articles', articleSchema);
//save to exports
module.exports = 'hi';
And here I try to call it:
var Articles = require('../../articles/models/articles.js');
console.log('a',require('../../articles/models/articles.js'));
console.log('b',Articles);
setTimeout(()=>{
console.log('c',require('../../articles/models/articles.js'));
console.log('d',Articles);
},1000);
But this is what it outputs:
a: {}
b: {}
c: hi
d: {}
Why is this happening? Where is the empty object coming from? It's clearly finding the correct file because there's no errors.
If I move module.exports = 'hi' to the top of articles.js though, then I get the proper "hi" for a, b, c, and d. But I'm trying to make it return the model object created in that document.
I can't figure out where the problem is occurring.
Edit: this seems to be a circular dependency issue. The Articles and Comments models both have functions that reference each other, because they both need to. I don't understand why they can't, or how to avoid with (with still keeping my code clean).

How can i generate child model in mongoose

I'm trying to model the following.
I have a parent model that is called Brick that has some attributes.
There will be 5+ type of bricks that will all have their own specific attributes wich are needed also.
I want to be able to select all Bricks of a certain custumer id later, whatever the type (TwitterBrick, facebookBrick et cetera) is.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// set up a mongoose model
module.exports = mongoose.model('Brick', new Schema({
type: String,
userid: { type: String, required: true},
animationspeed: { type: Number, min: 1, max: 100 },
socialsite: String, // none, twitter, instagram
socialsearchtags: String,
tagline: { type: String, minlength:3,maxlength: 25 },
}));
An example for a child is TwitterBrick.
for now it is:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
module.exports = mongoose.model('TwitterBrick', new Schema({
bgColor1: String,
bgColor2: String,
bannerBgColor1: String,
bannerBgColor2: String,
}));
TwitterBrick should inherit the attributes of Brick , but i don't know how..
Can you help me in the right direction?
Thanks!
Steven
My solution was to set a new "content" field in brickSchema, and split in different files:
brick.schema.js
var mongoose = require('mongoose');
module.exports = {
type: String,
userid: { type: String, required: true},
animationspeed: { type: Number, min: 1, max: 100 },
socialsite: String, // none, twitter, instagram
socialsearchtags: String,
tagline: { type: String, minlength:3,maxlength: 25 },
content: {type:mongoose.Schema.Types.Mixed, required: false, default: null}
}
brick.model.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var BrickSchema = new Schema(require('brick.schema.js'));
module.exports = mongoose.model('defaultBrick', BrickSchema, 'Bricks');
twitterBrick.model.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var brickSchema = require('brick.schema.js');
brickSchema.content = new Schema({
bgColor1: String,
bgColor2: String,
bannerBgColor1: String,
bannerBgColor2: String,
});
var BrickSchema = new Schema(require('brick.schema.js'));
module.exports = mongoose.model('twitterBrick', BrickSchema, 'Bricks');
Hope it helps !
Just add the Brick model as an attribute (composition).
It will compensate for that.
Or just rely on exisiting mongoose plugins for that https://github.com/briankircho/mongoose-schema-extend
check this one out.
That's because you didn't "require" the previous file, so technically it's out of scope and the TwitterWallBrickSchema doesn't have a clue what's a "BrickSchema".
Either you put the two models in the same file , or require the first file in the second file.

Whats the proper way to use mongoose population?

I have two schemas setup:
var ClientSchema = new Schema({
name: String
});
module.exports = mongoose.model('Client', ClientSchema);
And
var PlaceSchema = new Schema({
client: {type: mongoose.Schema.Types.ObjectId, ref: 'Client'},
address: String
});
module.exports = mongoose.model('Place', PlaceSchema);
If i get a list of places, i can populate the client easily like this:
Place.find({}).populate('client')
However, if i want to get a list of all the clients and all of their places, how would i make a query for that? Should i just simply loop through all of the clients and finding the places for it with Place.find({client:client._id) before returning the response?
Well if you have a number of places they will have their own unique ids, and for every place a client is connected to, you can have an array of placeId, you can push a placeId to this array everytime a client is connected to this place.`
var ClientSchema = new Schema({
name: String,
_address: [{type: mongoose.Schema.Types.ObjectId, ref: 'Place'}]
});`
This data structure would only work in one way, PlaceSchema do refer to ClientSchema but ClientSchema do not have any reference to PlaceSchema, the solution would be to define your ClientSchema this way :
var ClientSchema = new Schema({
name: String,
_address: [{type: mongoose.Schema.Types.ObjectId, ref: 'Place'}]
});
It seems kinda dumb but it would be much easier for your case

Node.js and mongoose module.exports on a model vs Schema

I have been following many tutorials concerning the MEAN stack, and I have come to a question I've found hard to answer (note: I found a possible duplicate when searching, but don't believe it answers my question)
Take this code for example, which can be found here
// app/models/nerd.js
// grab the mongoose module
var mongoose = require('mongoose');
// define our nerd model
// module.exports allows us to pass this to other files when it is called
module.exports = mongoose.model('Nerd', {
name : {type : String, default: ''}
});
After finishing the tutorial, I rewrote the code to attempt to replicate the lessons like so ("menu item" for a restraunt):
var mongoose = require('mongoose');
module.exports = mongoose.model('Item', {
name: {type: String, required: true},
description: {type: String, require: true},
price: {type: String, required: true},
ingredients: [{
name: {type: String, default: ''},
amt: {type: String, enum: ['None', 'Reg', 'XTRA'], required: true}
}]
});
I will be using an interface to create new menu items. Should I leave the code as is, or use a Schema?
Well. I was reading through code to post as an example for a difference, and came to this.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var BearSchema = new Schema({
name: String
});
module.exports = mongoose.model('Bear', BearSchema);
I then noticed that the schema was defined inline (I think?) instead of being declared. I would assume that this is because later, it will be much cleaner for me to add more schema declarations in this model, along with methods. If anyone can provide me with clarification, I'll give you the answer!

Resources