These are chat archives for Automattic/mongoose

1st
Jun 2018
Daniel Netzer
@DanielNetzer
Jun 01 2018 07:34
Morning all, what's the best way to return to client the field '_id' as 'id'?
Aurelio Decock
@auredeco
Jun 01 2018 09:15
Hey all, I just upgraded from mongoose 4.x to 5.x and got this error uncaughtException: schema.s.hooks.createWrapperSync is not a function. Any idea how to fix this?
Kev
@lineus
Jun 01 2018 09:17
@auredeco sounds like maybe kareem didn't get upgraded alongside mongoose?
Aurelio Decock
@auredeco
Jun 01 2018 09:18
When going through the structure of this app I cannot seem to find anything like kareem
(I'm completely new to this btw, this is my first experience with mongoDB/Mongoose/Node)
Kev
@lineus
Jun 01 2018 09:20
6548>: npm ls | grep kareem
│ ├── kareem@2.1.0
6548>:
you should see kareem installed wherever mongoose is installed
Aurelio Decock
@auredeco
Jun 01 2018 09:21
npm ls | grep kareem
│ │ ├── kareem@1.1.3
│ ├── kareem@2.1.0
this is what I'm getting, so I expect it's alright?
Kev
@lineus
Jun 01 2018 09:25
I would rename or remove the kareem@1.1.3 folder and try your app again ( or just remove node_modules and reinstall ). It sounds like mongoose is getting the wrong version of kareem.
Aurelio Decock
@auredeco
Jun 01 2018 09:25
Ok i'll give that a try, thanks :)
Kev
@lineus
Jun 01 2018 09:26
I hope it helps :smile:
Aurelio Decock
@auredeco
Jun 01 2018 09:27
I sure hope so too :smile:
Kev
@lineus
Jun 01 2018 09:27
@saeedhei I used passport, but everything you proposed sounds fine to me ( except the advertising part :fire: )
@DanielNetzer there's a virtual attached to all docs called id that will return the hex string representation of _id. doc.id will give you a 24 character string that mongoose can later cast into an ObjectId.
Aurelio Decock
@auredeco
Jun 01 2018 09:29
@lineus Hmmn looks like i've made things worse ...
Screen Shot 2018-06-01 at 11.28.31.png
Kev
@lineus
Jun 01 2018 09:30
what commands did you run @auredeco ?
Aurelio Decock
@auredeco
Jun 01 2018 09:30
rm -rf node_modules
npm install
Kev
@lineus
Jun 01 2018 09:32
can you create a gist of your package.json and share it here?
Aurelio Decock
@auredeco
Jun 01 2018 09:33
oh looks like I fixed the errors with npm update
but still got the createWrapper issue tho
Kev
@lineus
Jun 01 2018 09:33
do you still have both copies of kareem?
Aurelio Decock
@auredeco
Jun 01 2018 09:34
Yes I do
Kev
@lineus
Jun 01 2018 09:36
You can remove that older kareem dir and test, but the more curious problem is why you're getting both versions. can you paste your dependencies here from package.json?
Aurelio Decock
@auredeco
Jun 01 2018 09:36
"dependencies": {
    "agenda": "1.0.3",
    "bcryptjs": "^2.4.3",
    "bluebird": "^3.1.1",
    "body-parser": "~1.15.2",
    "config": "^1.15.0",
    "csv-write-stream": "^2.0.0",
    "excel-export": "0.5.1",
    "express": "~4.14.0",
    "express-prom-bundle": "^3.2.1",
    "express-winston": "^2.4.0",
    "find-remove": "^1.0.0",
    "huvepharma-aviapp-schemas": "~3.10.0",
    "is-my-json-valid": "^2.16.0",
    "lodash": "^4.17.10",
    "moment": "^2.22.2",
    "mongodb": "2.2.19",
    "mongodb-migrations": "^0.8.5",
    "mongoose": "^5.1.3",
    "mongoose-schema-jsonschema": "^1.1.13",
    "newrelic": "^1.35.1",
    "nodemailer": "4.0.1",
    "nodemailer-mailgun-transport": "1.3.5",
    "oauth2-server": "^2.4.1",
    "raven": "^1.1.1",
    "semver": "^5.4.1",
    "winston": "^2.4.2"
  },
  "devDependencies": {
    "chai": "^3.5.0",
    "debug": "~2.1.1",
    "eslint": "3.15.0",
    "eslint-config-itp-base": "1.0.1",
    "factory-lady": "^0.1.0",
    "faker": "^4.1.0",
    "husky": "^0.14.3",
    "istanbul": "~0.4.5",
    "lint-staged": "^7.1.3",
    "minimist": "*",
    "mocha": "^3.2.0",
    "mocha-junit-reporter": "^1.13.0",
    "mocha-mongoose": "^1.0.4",
    "nodemon": "^1.17.5",
    "prettier": "^1.13.3",
    "sinon": "^3.2.1",
    "supertest": "^2.0.1"
  }
there you go
Kev
@lineus
Jun 01 2018 09:51
I installed your dependencies in a new package and only got one copy of kareem, I did have to remove one package from the list: huvepharma-aviapp-schemas.

then I ran a simple test:

#!/usr/bin/env node
'use strict';

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
const conn = mongoose.connection;
const Schema = mongoose.Schema;

const schema = new Schema({
  name: String
});

schema.pre('save', function() {
  console.log('saving');
});

const Test = mongoose.model('test', schema);

const test = new Test({
  name: 'billy'
});

async function run() {
  await conn.dropDatabase();
  await test.save();
  let found = await Test.findOne();
  console.log(found);
  return conn.close();
}

run();

output:

auredeco: ./test.js
saving
{ _id: 5b1116ff4aa83e15d61c3052, name: 'billy', __v: 0 }
auredeco:
you can use something like this from your package dir to see which kareem is being used:
node -e "x=require.resolve('kareem').replace(/[^\/]+$/, 'package.json');console.log(x)"
Aurelio Decock
@auredeco
Jun 01 2018 09:53
that's really weird
Kev
@lineus
Jun 01 2018 09:54
you don't strictly need the string replacement, that's just an artifact of the bash function I ripped that out of :smile:
Aurelio Decock
@auredeco
Jun 01 2018 09:55
Well I run the node command and it returned 1 path
when I follow the path i get to the kareem 2.1.0
Kev
@lineus
Jun 01 2018 09:55
did you remove the other kareem already?
Aurelio Decock
@auredeco
Jun 01 2018 09:55
I do not know where to find it
it's really weird
because when I grep, I get 2 values, but when I log the node command I only get one
Kev
@lineus
Jun 01 2018 09:57
auredeco: find node_modules -type d -name '*kareem*'
node_modules/kareem
auredeco:
Aurelio Decock
@auredeco
Jun 01 2018 09:58
aha!
that got me 2 outputs
And it looks it's a dependency that this company wrote themselves that got that version
Aurelio Decock
@auredeco
Jun 01 2018 10:08
So it's a dependency of a dependency, So normally it shouldn't break things in this app right?
Kev
@lineus
Jun 01 2018 10:09
that's correct
was it the package that I removed from my version of your package.json huvepharma-aviapp-schemas ?
Aurelio Decock
@auredeco
Jun 01 2018 10:11
yes
that's the one who got the kareem 1.x
But first of all I got the error connection.model is not a function so I changed my mongoose.connect() to mongoose.createConnection(). Is it possible that that change broke something?
Kev
@lineus
Jun 01 2018 10:16
how was connection defined before you called connection.model ?
Aurelio Decock
@auredeco
Jun 01 2018 10:17
const config = require('config');
const mongoose = require('mongoose');
const logger = require('./util/logger');

require('mongoose-schema-jsonschema')(mongoose);

const connectionOptions = {
  server: {
    socketOptions: {
      keepAlive: 1,
    },
  },
  config: { autoIndex: false },
};

mongoose.Promise = require('bluebird');

/**
 * Mongoose opened a connection
 */
mongoose.connection.on('open', () => {
  logger.info(`Connected to mongo server. ${process.env.MONGO_URL || config.get('db.uri')}`);
});

/**
 * Mongoose errored with a connection
 */
mongoose.connection.on('error', err => {
  logger.error('Could not connect to mongo server!');
  logger.error(err);

  // This forces node to actually exit the process, allowing kubernetes to handle the problem.
  // i.e. restart this container untill it can actually correctly connect to the mongo container
  process.exit(1);
});
module.exports = mongoose.connect(
  process.env.MONGO_URL || config.get('db.uri'),
  connectionOptions
);
This is what connection.js looks like
const connection = require('../connection');
const HuveSchema = require('huvepharma-aviapp-schemas');
const SecurityHelper = require('../helper/security_helper');

const AccessToken = connection.model('AccessToken', HuveSchema.AccessToken);

AccessToken.securityQueryType = SecurityHelper.ruleTypes.unrestricted;
AccessToken.securityWriteType = SecurityHelper.ruleTypes.unrestricted;
AccessToken.securityCompletionType = SecurityHelper.completionTypes.noCompletion;

module.exports = AccessToken;
And this is how it's used
so when I changed mongoose.conntect() to mongoose.createConnection() I fixed that error, but then got the createWrapperSync one instead
Kev
@lineus
Jun 01 2018 10:30
mongoose.connect() returns a promise that resolves to this (mongoose) whereas mongoose.createConnection() returns the connection. Gist here
Aurelio Decock
@auredeco
Jun 01 2018 10:31
Owh, did it always return a promise or was that updated?
Kev
@lineus
Jun 01 2018 10:31
in the version 4 docs it says that the return from connect was a mongoose thenable, which may have led to a different behavior, but I'm not certain.
Aurelio Decock
@auredeco
Jun 01 2018 10:32
alright, I'll try to .then it :)
Aurelio Decock
@auredeco
Jun 01 2018 10:53
nope, still doesn't work... :/
same issue
Kev
@lineus
Jun 01 2018 10:55
can you make a gist or paste here the current code where you're importing connect ?
Aurelio Decock
@auredeco
Jun 01 2018 10:56
it's right above here
the first snippet is the connection export
and the second snippet is the usage
const connection = require('../connection');
const HuveSchema = require('huvepharma-aviapp-schemas');
const SecurityHelper = require('../helper/security_helper');

const AccessToken = connection.then(conn => {
  conn.model('AccessToken', HuveSchema.AccessToken)
;});

AccessToken.securityQueryType = SecurityHelper.ruleTypes.unrestricted;
AccessToken.securityWriteType = SecurityHelper.ruleTypes.unrestricted;
AccessToken.securityCompletionType = SecurityHelper.completionTypes.noCompletion;

module.exports = AccessToken;
And this is what it looks like with .then()
Kev
@lineus
Jun 01 2018 11:01
that's what I was looking for. Now AccessToken is a promise, so wherever you import that will need to call .then()to get at the actual model. at least that's what my cerebral-compiler is telling me :smile:
Aurelio Decock
@auredeco
Jun 01 2018 11:02
Damn son
might aswell rewrite the whole thing
Kev
@lineus
Jun 01 2018 11:03
const AccessToken = require('./accesstoken').then(model => model); prolly
Aurelio Decock
@auredeco
Jun 01 2018 11:03
hmmmn
and can't I do something like
connection.then(conn => {
  conn.model('AccessToken', HuveSchema.AccessToken)
;}).then(model => model);
won't that work?
Kev
@lineus
Jun 01 2018 11:20
I think the easiest way to deal with it, is to not rely on the connection being established before you attach your model. Mongoose will allow you to create models and the connection in either order, buffering commands until the connection is complete. here is how I would do it
Aurelio Decock
@auredeco
Jun 01 2018 11:22
Hmmmn, won't the app need a refactor aswell when I approach it like this?
I mean, I'm currently upgrading a finished project
Kev
@lineus
Jun 01 2018 11:23
I have to run my kids to school, back in 15ish mins
Aurelio Decock
@auredeco
Jun 01 2018 11:23
Sure man, drive safe!
Kev
@lineus
Jun 01 2018 12:30
it shouldn't be terribly difficult, my first thought is that you just have to replace connection.model with mongoose.model everywhere. mongoose will do the right thing and buffer commands until the connection is established. This will require you to require mongoose in more files probably as well but that won't impact anything.
Aurelio Decock
@auredeco
Jun 01 2018 13:52
I might try to convince my Solution Architect to change that indeed, I'll see what he has to say monday when he gets back. Thanks for helping, I really appreciate it! :)
Daniel Netzer
@DanielNetzer
Jun 01 2018 14:48
@lineus can you direct me to some documetation how to use that virtual to return the _id field as id?
Kev
@lineus
Jun 01 2018 14:58
@DanielNetzer it's just a simple getter on the document, const string = doc.id example
Chris Rutherford
@cjrutherford
Jun 01 2018 17:00

Hey guys, I'm having a weird issue when launching my app. I'm trying to test it now that I've gotten the routes for my model in place, but I'm getting this error:
TypeError: Cannot read property 'push' of undefined at Function.route (c:\Users\rutherfordc\Documents\GitHub\ccs-express-mongo\node_modules\express\lib\router\index.js:502:14) at Function.proto.(anonymous function) [as get] (c:\Users\rutherfordc\Documents\GitHub\ccs-express-mongo\node_modules\express\lib\router\index.js:509:22) at Object.<anonymous> (c:\Users\rutherfordc\Documents\GitHub\ccs-express-mongo\routes\insider.js:8:8) at Module._compile (module.js:652:30) at Object.Module._extensions..js (module.js:663:10) at Module.load (module.js:565:32) at tryModuleLoad (module.js:505:12) at Function.Module._load (module.js:497:3) at Module.require (module.js:596:17) at require (internal/module.js:11:18) at Object.<anonymous> (c:\Users\rutherfordc\Documents\GitHub\ccs-express-mongo\index.js:36:25) at Module._compile (module.js:649:14) at Object.Module._extensions..js (module.js:663:10) at Module.load (module.js:565:32) at tryModuleLoad (module.js:505:12) at Function.Module._load (module.js:497:3)

I have my routes defined like this in index.js app.use('/api/insider', require('./routes/insider')); and the "error" on Insider.js:8:8 looks like this: Router.get('/:insiderId', (req, res) => { Insider.findOne({ _id: req.params.insiderId }) .populate('area', ['areaCode']) .populate('contacts', [ 'outsider', 'initialDate', 'earlyExpiration', 'lateExpiration' ]) .then(insider => { if (!profile) res.status(400).json({ error: 'Insider Not Found' }); res.json(profile); }) .catch(err => log.error(err)); });

What gives?

Kev
@lineus
Jun 01 2018 17:09
it's kinda hard to read, but this looks off .populate('area', ['areaCode']). it should be .populate('area', 'areaCode')
Chris Rutherford
@cjrutherford
Jun 01 2018 17:10
Okay so if I'm understanding you in populate, if I only want one field year it out of the array? Okay that works! Thanks @lineus
Kev
@lineus
Jun 01 2018 17:10
.populate('contacts', [ 'outsider', 'initialDate', 'earlyExpiration', 'lateExpiration' ]) should be .populate('contacts', 'outsider initialDate earlyExpiration lateExpiration')
the select parameter is always going to be a space separated string
Chris Rutherford
@cjrutherford
Jun 01 2018 17:11
Sorry for the bad layout. Been forever since I was on gutter.. okay, no idea where the idea it should be an array came from...
Kev
@lineus
Jun 01 2018 17:12
seems like a reasonable thing to do, I suppose it could have gone either way ( or both ).
Chris Rutherford
@cjrutherford
Jun 01 2018 17:16
Lol one of these days I'll be answering the questions! Thanks again @lineus
Kev
@lineus
Jun 01 2018 17:17
happy to help!
Chris Rutherford
@cjrutherford
Jun 01 2018 18:02

hey sorry, it's still not working:

const Insider = require('../models/insider');
const mongoose = require('mongoose');
const Contact = require('../models/contacts');
const router = require('express').Router;
const log = require('../logger');
const util = require('../util');

router.get('/:insiderId', (req, res) => {
  Insider.findOne({ _id: req.params.insiderId })
    .populate('area', 'areaCode')
    .populate('contacts', 'outsider initialDate earlyExpiration lateExpiration')
    .then(insider => {
      if (!profile) res.status(400).json({ error: 'Insider Not Found' });
      res.json(profile);
    })
    .catch(err => log.error(err));
});

still throws the error:

TypeError: Cannot read property 'push' of undefined
    at Function.route (c:\Users\rutherfordc\Documents\GitHub\ccs-express-mongo\node_modules\express\lib\router\index.js:502:14)
    at Function.proto.(anonymous function) [as get] (c:\Users\rutherfordc\Documents\GitHub\ccs-express-mongo\node_modules\express\lib\router\index.js:509:22)
    at Object.<anonymous> (c:\Users\rutherfordc\Documents\GitHub\ccs-express-mongo\routes\insider.js:8:8)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (c:\Users\rutherfordc\Documents\GitHub\ccs-express-mongo\index.js:36:25)
    at Module._compile (module.js:649:14)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
line 8 in insider.js is the router.get line
this is more of an express issue, and not a mongoose issue, so I'll ask there, if anyone's around
Kev
@lineus
Jun 01 2018 18:07
const router = require('express').Router; should maybe be const router = require('express').Router(); ?
note the () after Router.
Chris Rutherford
@cjrutherford
Jun 01 2018 18:07
ughhh.... I forgot it was a constructor.....
Chris Rutherford
@cjrutherford
Jun 01 2018 18:14
that was it! thanks yet again!
Mark Williams
@readysetmark
Jun 01 2018 20:21
Hello! How would I get the object undergoing validation in a pre-validate hook? this doesn't seem to work, and it doesn't look like it gets passed in as an arg to the event handler?
Kev
@lineus
Jun 01 2018 20:21
@readysetmark it shoud be this. can you share your schema and hooks?
should be this unless it's an update validator
Mark Williams
@readysetmark
Jun 01 2018 20:22
Yeah, here ok, or should I make a gist?
Kev
@lineus
Jun 01 2018 20:22
if it's an update validator, this is the query.
your call, more than 30ish lines a gist is probably better.
Mark Williams
@readysetmark
Jun 01 2018 20:23
I'm just calling .validate() on the object. I'll make a gist. One sec.
Kev
@lineus
Jun 01 2018 20:23
cool
Kev
@lineus
Jun 01 2018 20:45
@readysetmark my theory is that the value of this being an empty object in pre-validate is intentional, I'm looking at the source now to verify.
I'm guessing it doesn't set the value of the path until validation is complete.
Mark Williams
@readysetmark
Jun 01 2018 20:50
Hm, interesting. Just tried post-validate and it's the same thing.
Kev
@lineus
Jun 01 2018 20:50
hah
Mark Williams
@readysetmark
Jun 01 2018 20:51
as in, also empty.
Kev
@lineus
Jun 01 2018 20:51
I was just doing the same thing, even post save was empty. even tried another version of mongoose
I'm missing something simple, I can feel it :smile:
Mark Williams
@readysetmark
Jun 01 2018 20:51
That's how I was feeling. :D
Kev
@lineus
Jun 01 2018 20:53
oh jesus
it's the arrow functions
Mark Williams
@readysetmark
Jun 01 2018 20:53
really??
Kev
@lineus
Jun 01 2018 20:53
my head is really somewhere else today
Mark Williams
@readysetmark
Jun 01 2018 20:54
Yes, I see, changing to function (next) instead works...
Kev
@lineus
Jun 01 2018 20:54
that's usually the first thing I look for :)
Mark Williams
@readysetmark
Jun 01 2018 20:54
Are arrow functions not just sugar for the same thing?
Haven't written a ton of JavaScript, but I was under the impression they were...
Kev
@lineus
Jun 01 2018 20:55
definitely not, this is not the same between common functions and arrow functions
Mark Williams
@readysetmark
Jun 01 2018 20:56
oooh, yes, just pulled up the mdn doc on arrow functions and see that "it does not have it's own this"
heh, yeah, that :)
Mark Williams
@readysetmark
Jun 01 2018 20:57
Nice, I'll have to be more mindful about how I use them!
Thank you very much for your help!
Kev
@lineus
Jun 01 2018 20:57
I've spent the last 9 hours trying to debug a yarn issue, I think it's time to step away and stand in the rain.
anytime!