Solvedobjection.js Class constructor Model cannot be invoked without 'new'

I'm getting the following error after upgrading to 0.8.0:

TypeError: Class constructor Model cannot be invoked without 'new'
  at new UserModel (/path/to/project/src/server/graphql/models/User/userModel.js:29:103)
  at Function.fromDatabaseJson (/path/to/project/node_modules/objection/lib/model/Model.js:443:19)
  at Object.createModels (/path/to/project/node_modules/objection/lib/queryBuilder/QueryBuilder.js:826:41)
  at Object.tryCatcher (/path/to/project/node_modules/bluebird/js/release/util.js:16:23)
  at Promise._settlePromiseFromHandler (/path/to/project/node_modules/bluebird/js/release/promise.js:512:31)
  at Promise._settlePromise (/path/to/project/node_modules/bluebird/js/release/promise.js:569:18)
  at Promise._settlePromise0 (/path/to/project/node_modules/bluebird/js/release/promise.js:614:10)
  at Promise._settlePromises (/path/to/project/node_modules/bluebird/js/release/promise.js:693:18)
  at Async._drainQueue (/path/to/project/node_modules/bluebird/js/release/async.js:133:16)
  at Async._drainQueues (/path/to/project/node_modules/bluebird/js/release/async.js:143:10)
  at Immediate.Async.drainQueues (/path/to/project/node_modules/bluebird/js/release/async.js:17:14)
  at runCallback (timers.js:672:20)
  at tryOnImmediate (timers.js:645:5)
  at processImmediate [as _immediateCallback] (timers.js:617:5)
41 Answers

✔️Accepted Answer

You can also make it so that babel is using your node version by doing something like this:

{
  "presets": [
    ["env", {
      "targets": {
        "node": "current"
      }
      }],
    "stage-1"
  ],
  "plugins": []
}

Other Answers:

If using TypeScript compiler, set output to at least es2015 in tsconfig.json

{
  "compilerOptions": {
     "target": "es2015"
  }
}

I am trying to use objection.js with Node in AWS Lambda (Node 8.10). I struggled for a few hours until I hit the jackpot. I tried several configuration recommendations and what finally did the trick was excluding the babel-plugin-transform-classes in the preset-env options. I share this for future reference, since it may help others searching for the same solution.

Cheers!

// webpack.config.js

...

{
  test: /\.(js|jsx)$/,
  exclude: /node_modules/,
  use: {
    loader: 'babel-loader',
    options: {
      presets: [
        [
          '@babel/preset-env',
          {
            target: { node: '8.10' }, // Node version on AWS Lambda
            modules: false,
            exclude: ['babel-plugin-transform-classes'],
          },
        ],
      ],
      plugins: [
        '@babel/plugin-proposal-class-properties',
        '@babel/plugin-proposal-object-rest-spread',
        '@babel/plugin-transform-runtime',
      ],
    },
  },
},

...

EDIT:
As of objection 1.5.0 this problem should no longer exist. But please, stop transpiling your backend to ES5 in the year 2019! That's idiotic! Target node 6 in your babel config instead. Node 6, that has everything objection needs, was released four years ago! Surely you are not using node versions < 6 are you? Transpiling to ES5 will, among other things, use regenerator to rewrite your async/await code into a switch/case state machine that adds quite a bit of overhead.
END EDIT

Yep, please read the change log. Legacy node versions (0.10, 0.12) are no longer supported. You also need to migrate from the legacy ES5 inheritance to class and extend keywords. This is because of the way classes are implemented in Ecmascript. You cannot invoke class constructors without new and therefore this doesn't work:

class Model {

}

function UserModel() {
  // You cannot do this.
  Model.apply(this, arguments);
}

And since objection Model is a native ES2015 class, you get that error. If you are using Babel you need to remove the babel-plugin-transform-es2015-classes plugin that does the conversion. You don't need it anyway with node >= 4.0.0.

Check out the ESNext example project as an example of how to setup babel.

Yeah this is difficult. My JS environment is pretty crazy because I'm using Razzle for server-side rendering of a React app, and I use react-native-web to share code with iOS/Android with the same codebase.

Because I'm using Razzle, I don't have full access to my full webpack+babel config. Even if I could edit my config, it would feel hacky to carve out an exception for objection.

Long story short, I found it easier to fork and compile objection to ES5+CommonJS, so that I don't hit this error. If anybody else wants to use my compiled version, you can add the following to your package.json:

    "objection": "https://github.com/ericvicenti/objection.js",