Solution Found: Turns out the problem was a "circular" dependency. For anyone who else might encounter this problem, I found the answer here: Require returns an empty object
First time asking a question. I'm still learning, and I thought I knew what I was doing here, but I can't make sense of this.
I am working on a Node project with MongoDB/Mongoose. At the top of my file, I have:
const {Institution} = require('./institution');
const {Student} = require('./student');
When I run my program and use Institution.findOne() it errors and says cannot read property findOne of undefined. I use the Institution model in several other files and they all work fine.
The model is required in several steps before this one and always works fine. Since the model works in other cases, I would think the exports are working just fine.
const Institution = database.model('Institution', InstitutionSchema);
module.exports = {
Institution,
InstitutionSchema
};
Both institution.js and student.js are in the same folder as this file.
When I do console.log(Student), it returns the huge Mongoose object.
When I do console.log(Institution), it returns undefined.
If I console.log(Institution) from another module where it is working, it returns the Mongoose object.
The Institution collection is in my database and I can view the content in Robomongo viewer.
Am I missing something that I just can't see?
Thanks in advance for any help.
Related
I refactored some code that passed on an object as a require to use it from a feature file and now I get the error on the title.
Previously:
const schema = require (´path to schema´)
let schemafile = [schema]
Now:
const schemafile = (fs.readFileSync(__dirname+'path to schema'+schema+.js)toString())
the above passed the contents of the joi schema file I prepared, but when i do:
joi.assert (responsebody, schemafile)
or
joi.attempt(responsebody, schemafile)
I get the error
TyperError: schema.validate is not a function
I do have the require for joi, and it seems everything passes fine and the error seems to be internal to joi, as the expression does exist there. What I can't make up is why it used to work before. Rolling back is not an option because I modified many, many files before I got this to hit that part of the code.
Sorry if the code is too vague but I cannot share much more (can't even copypaste from the VDI I use).
I use joi's latest version, I know joi.validate was deprecated and it is not used anywhere in my code.
Any help is appreciated.
Thanks!
PS: I am new to js, node and joi so sorry if the question is too basic.
I'm brand new to coding, but decided to give it a shot just to make a fun little bot for a Discord server to surprise my friends, but I'm having a bit of an issue with refactoring in Visual Code Studio - for some reason, my forEach code isn't working all of a sudden, and I can't seem to figure out why or how to fix it,
here's the error I'm getting whenever I try to run it
files.forEach(file => {
^
TypeError: Cannot read property 'forEach' of undefined
and here's the section of code I'm using
fs.readdir("./events/", (err, files) => {
files.forEach(file => {
const eventHandler = require('./events/message.js')
const eventmessage = file.split(".")[0]
client.on(eventmessage, (...args) => eventHandler(client,...args))
})
Like I said, I'm new at coding, and have largely been following online guides, but I've tried a few things, such as removing it, restarting the program, rewriting it in a different window to see that does anything, reinstalling what I'm using in the code, and so on
I'm probably being an absolute idiot and missing some piece but I'm totally baffled so any guidance (or a different way to refactor!) would help!
Thank you in advance!
Note: I am largely following this guide if that helps any!
https://thomlom.dev/create-a-discord-bot-under-15-minutes/
EDIT: Here's a coded copy of what I've been following, as far as I can see my code is basically exactly the same
https://github.com/thomlom/discord-bot-example
Maybe you forgot to create the events folder, because I got the same error when the folder doesn't exist.
Try to follow this part of the tutorial again
To modularize our code, we will create an events folder. This folder will contain .js files whose name will match the different events name discord.js listens to:
Create an events folder.
In this folder, create three files: ready.js, message.js and guildMemberAdd.js.
I'm attempting to use a cursor:
const cursor = Thing.find({}).cursor();
cursor.next().then((a,b) => { console.log(a); console.log(b); })
But this never resolves; it just sits there. There doesn't seem to be a cursor.exec() or anything like that. cursor.close() even throws TypeError: Cannot read property 'close' of null.
All the documentation I can find ignores this and just goes about its example, thus implying I don't need it. But I quite obviously do, as it doesn't actually load any documents from Mongo.
This is on a legacy project and I'm unable to change the version of Mongoose. Node is 8.15.0, MongoDB is 3.2, and both are in a similar boat.
Ok, look, I'm going to own up to my stupidity here and admit that I hadn't actually connected to mongo before attempting to load the data. I'm also going to leave this question up as a combination of reference and penance.
Though to be fair I have no idea why mongoose wouldn't tell me it's not connected instead of blocking on a nonexistent connection. But I still should have known.
I have two different files in the same folder, both with the same code for importing in them.
import { PartialOne, PartialTwo } from 'components/partials'
console.log(PartialOne);
In the first file, the importing works correctly and the PartialOne function is displayed in the console. In the second, PartialOne is logged as undefined.
To make sure, I also tried:
import * as partials from 'components/partials'
console.log(partials);
And it returned an object-esque thing that had PartialOne and PartialTwo as properties. So, I'm pointing to the right exported file in both files that are trying to import it, but something is getting messed up, and can't figure out what.
I'm not sure what's going on so it's hard to know what to search for in Google/SO, but if there's another related SO question that would be helpful to have too.
(From the comment by loganfsmyth):
Check if there is a cycle in your dependency graph. That usually leads to issues like this, e.g. the export class ParitalOne {} line hasn't run yet, so the value shows as undefined
Many resources on the internet (including here) suggest using Meteor.startup to fix dependency issues caused by the order in which JS files load. However, nobody spells out exactly how this is accomplished.
Specifically, it seems like file order dependency is the reason I can't get my posts.coffee collection to recognize permissions defined in my permissions.coffee. I think this is happening because posts.coffee is in /lib/collections, whereas permissions.coffee is in /lib, and files in subdirectories get loaded first. (Incidentally, I would prefer /collections to be in the root directory, but I had to move it into /lib previously to solve a similar problem.)
Here is my posts.coffee:
#Posts = new Meteor.Collection('posts')
Posts.allow(
update: ownsDocument
remove: ownsDocument
)
Meteor.methods(
...
And here is my permissions.coffee:
#ownsDocument = (userId, doc)->
doc && doc.userId == userId
(This is all from the "Discover Meteor" book tutorial, by the way, around these commits, except in CoffeeScript.)
My question: Assuming my analysis of the problem is correct, how would you solve it using Meteor.startup? This answer is hard for me to interpret; one interpretation is that I should wrap Posts.allow(...) in Meteor.startup somehow, but that seems really clumsy. Maybe I'm wrong, but it seems like there should be one general/config file with all the necessary startup code, and specific controllers should remain ignorant of it.
BTW, I realize I could hack a solution by taking advantage of Meteor's default file load ordering rules (e.g. /lib first; subdirectories first; main.* last; alphabetically), but that's a really inelegant solution to what should be a simple problem. I don't want to have to append "a" in front of a filename or create spurious directories just to get it load before another file.
One last note: I'm using CoffeeScript, and I wonder if the way CS handles global scope has something to do with it. (E.g., instead of defining my Posts collection as a JS variable without the var keyword, in CS I have to define is as #Posts, which I believe makes it a property of the window.)
Yes, you do just that:
Meteor.startup ->
Posts.allow(
...
)
Basically, any piece of code that uses a variable defined in another file should be preceded by Meteor.startup ->, unless you are sure that the loading order is correct (the variable is in lib, for example).
Yes, the loading order is poorly chosen.
I highly suggest you consider working entirely out of smart packages. That's how Meteor itself is largely written.
I go into more detail here: http://www.matb33.me/2013/09/05/meteor-project-structure.html