vadimdemedes / mongorito

🍹 MongoDB ODM for Node.js apps based on Redux
1.38k stars 90 forks source link

TypeError: this.Model.query(...).then is not a function #208

Closed wesleycoder closed 6 years ago

wesleycoder commented 6 years ago

🐛 Trying to call .find and nothing works

I'm using mongorito with graphql and at some point .find stopped working.

You can see my project code here.

package.json: ```json { "name": "tavern-api", "version": "0.0.1", "main": "index.js", "repository": "git@github.com:TavernLab/tavern-api.git", "author": "Wésley Queiroz (https://github.com/wescoder)", "license": "MIT", "scripts": { "start": "run-s -nc api", "dev": "run-p api:dev", "api": "pm2 start ecosystem.config.js --only tavern-api", "api:dev": "pm2 start ecosystem.config.js --only tavern-api-dev", "app:dev": "node -- 'google-chrome'", "opn:app:dev": "opn https://localhost:8080 -- 'google-chrome'", "opn:api:dev": "opn https://localhost:8081 -- 'google-chrome'", "postinstall": "nisd front" }, "engines": { "node": "^9" }, "devDependencies": { "@types/node": "^9.4.0", "babel-plugin-inline-import-graphql-ast": "^2.0.4", "babel-polyfill": "^6.26.0", "babel-preset-env": "^1.6.1", "babel-preset-stage-0": "^6.24.1", "babel-register": "^6.26.0", "dotenv": "^4.0.0", "eslint": "^4.16.0", "eslint-config-standard": "^11.0.0-beta.0", "eslint-plugin-import": "^2.8.0", "eslint-plugin-node": "^5.2.1", "eslint-plugin-promise": "^3.6.0", "eslint-plugin-standard": "^3.0.1", "migrate": "^1.2.0", "nisd": "^0.0.4", "npm-run-all": "^4.1.2", "opn-cli": "^3.1.0", "pm2": "^2.9.3" }, "dependencies": { "@koa/cors": "^2.2.1", "apollo-server-koa": "^1.3.2", "graphql": "^0.12.3", "graphql-custom-types": "^1.3.0", "graphql-tools": "^2.19.0", "koa": "^2.4.1", "koa-bodyparser": "^3.2.0", "koa-mount": "^3.0.0", "mongorito": "^3.0.4", "mongorito-timestamps": "^1.0.1" } } ```
db/models/Player.js ```js import { Model } from 'mongorito' export class Player extends Model { } export default Player ```
db/models/index.js ```js import Board from './Board' import Player from './Player' export * from './Board' export * from './Player' export const models = [ Board, Player ] export default models ```
db/index.js ```js import { Database } from 'mongorito' import timestamps from 'mongorito-timestamps' import 'dotenv/config' import models from './models' const { MLAB_USER, MLAB_PASSWORD, MLAB_ENDPOINT } = process.env export const db = new Database(`mongodb://${MLAB_USER}:${MLAB_PASSWORD}@${MLAB_ENDPOINT}`) models.forEach((model) => { model.use(timestamps) db.register(model) }) export const connection = db.connect() export default connection ```

Mongorito fails here:

schema/resolver.js ```js import { Board, Player } from '../db/models' import { GraphQLEmail, GraphQLURL, GraphQLDateTime, GraphQLUUID } from 'graphql-custom-types' export const resolvers = { Email: GraphQLEmail, UUID: GraphQLUUID, Url: GraphQLURL, Date: GraphQLDateTime, Query: { players: async () => (await Player.find()).map(p => p.get()), // mongorito fails on .find here boards: async () => (await Board.find()).mp(b => b.get()) }, Mutation: { addPlayer: async (_, {playerData}) => { const player = new Player(playerData) await player.save() return player } } } export default resolvers ```
Error stacktrace: ``` TypeError: this.Model.query(...).then is not a function message: "this.Model.query(...).then is not a function" stack: "TypeError: this.Model.query(...).then is not a function at Query.find (/home/dev/tavern-api/node_modules/mongorito/lib/query.js:20:5) at Function.Model.(anonymous function) [as find] (/home/dev/tavern-api/node_modules/mongorito/lib/model.js:217:23) at _callee$ (/home/dev/tavern-api/schema/resolver.js:16:33) at tryCatch (/home/dev/tavern-api/node_modules/regenerator-runtime/runtime.js:65:40) at Generator.invoke [as _invoke] (/home/dev/tavern-api/node_modules/regenerator-runtime/runtime.js:303:22) at Generator.prototype.(anonymous function) [as next] (/home/dev/tavern-api/node_modules/regenerator-runtime/runtime.js:117:21) at step (/home/dev/tavern-api/schema/resolver.js:12:191) at /home/dev/tavern-api/schema/resolver.js:12:437 at new Promise () at /home/dev/tavern-api/schema/resolver.js:12:99 at players (/home/dev/tavern-api/schema/resolver.js:16:5) at resolveFieldValueOrError (/home/dev/tavern-api/node_modules/graphql/execution/execute.js:544:18) at resolveField (/home/dev/tavern-api/node_modules/graphql/execution/execute.js:508:16) at /home/dev/tavern-api/node_modules/graphql/execution/execute.js:357:18 at Array.reduce () at executeFields (/home/dev/tavern-api/node_modules/graphql/execution/execute.js:354:42)" __proto__: Error {constructor: , name: "TypeError", message: "", …} ```
wesleycoder commented 6 years ago

Debugging a little bit more: this.Model.query('find', this.query) on mongorito/lib/query.js:19 returns action => { … } instead of a promise.

wesleycoder commented 6 years ago

I've got it to work, but don't know exactly what was the solution.

Here's what I've done: First I noticed I had followed the example in the readme into using mongorito-timestamps but it was missing parenthesis (see #202). Second I've disabled babel caching by setting BABEL_DISABLE_CACHE=1 on my environment and using a task on my package.json to clear it inside babel module "clear:babel": "rimraf -rf ./node_modules/.cache/babel-loader/*".

It seems that using mongorito-timestamps in the wrong way will not throw any errors or warning and will cause a unexpected behavior on mongorito.

I think the middleware should be validated by mongorito and throw an warning or error if it is not providing the expected behavior.

wesleycoder commented 6 years ago

I've got it working, but I'm unsure what exactly make it happen. I've disabled babel caching, cleaned node_modules and reinstalled, also I've fixed mongorito-timestamps usage, that was:

model.use(timestamps)

and should be:

model.use(timestamps())

One of those things actually made it work, but I'm unsure. I'm closing this as it is not affecting me anymore. I'll be subscribed if anyone has the same issue.