Asked it here: https://stackoverflow.com/questions/50272405/sequelize-typescript-typeerror-class-constructor-model-cannot-be-invoked-withou
Repo to reproduce here: https://github.com/avidanyum/test-node-sequelize (see below exact steps).
I'm using sequelize-typescript when I run a sample mocha test to check it I get:
TypeError: Class constructor Model cannot be invoked without 'new'
I saw some related questions over the net but I am using latest transpiler to javascript from typescript see:
backend/tsconfig.json:
"target": "es2017",
"lib": [
"es2017",
The relevant code is:
backend/src/test/ts/transaction.async.mocha.test.ts:
@Table
export class User extends Model<User> {
@Column({primaryKey: true})
id: string;
@Column
name: string;
}
async function asyncSaveAndFindTest(): Promise<User[]> {
return await new User({ name: 'someName' }).save().then(res => User.findAll());
}
Here is how to reproduce the problem:
➜ tmp git clone https://github.com/avidanyum/test-node-sequelize
Cloning into 'test-node-sequelize'...
remote: Counting objects: 23, done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 23 (delta 2), reused 23 (delta 2), pack-reused 0
Unpacking objects: 100% (23/23), done.
➜ tmp cd test-node-sequelize
➜ test-node-sequelize git:(master) npm install
> [email protected] install /Users/myuser/tmp/test-node-sequelize/node_modules/sqlite3
> node-pre-gyp install --fallback-to-build
[sqlite3] Success: "/Users/myuser/tmp/test-node-sequelize/node_modules/sqlite3/lib/binding/node-v57-darwin-x64/node_sqlite3.node" is installed via remote
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN [email protected] requires a peer of @angular/compiler@>=2.3.1 <7.0.0 || >6.0.0-beta <7.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of @angular/core@>=2.3.1 <7.0.0 || >6.0.0-beta <7.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of @angular/platform-browser-dynamic@>=2.3.1 <7.0.0 || >6.0.0-beta <7.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of @angular/platform-browser@>=2.3.1 <7.0.0 || >6.0.0-beta <7.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of @angular/common@>=2.3.1 <7.0.0 || >6.0.0-beta <7.0.0 but none is installed. You must install peer dependencies yourself.
added 649 packages in 21.194s
➜ test-node-sequelize git:(master) npm run-script test-mocha
> [email protected] test-mocha /Users/myuser/tmp/test-node-sequelize
> mocha --require ts-node/register ./backend/src/test/ts/**/*.mocha.test.ts
sequelize deprecated String based operators are now deprecated. Please use Symbol based operators for better security, read more at http://docs.sequelizejs.com/manual/tutorial/querying.html#operators node_modules/sequelize/lib/sequelize.js:242:13
DB Model Test
Executing (default): SELECT 1+1 AS result
Executing (default): CREATE TABLE IF NOT EXISTS `User` (`id` VARCHAR(255) PRIMARY KEY, `name` VARCHAR(255));
Executing (default): PRAGMA INDEX_LIST(`User`)
Executing (default): PRAGMA INDEX_INFO(`sqlite_autoindex_User_1`)
Executing (default): CREATE TABLE IF NOT EXISTS `User` (`id` VARCHAR(255) PRIMARY KEY, `name` VARCHAR(255));
Executing (default): PRAGMA INDEX_LIST(`User`)
Executing (default): PRAGMA INDEX_INFO(`sqlite_autoindex_User_1`)
Executing (2d1b9e42-32c2-4103-8f1d-17ad02279bd3): BEGIN DEFERRED TRANSACTION;
before add user 1
Executing (2d1b9e42-32c2-4103-8f1d-17ad02279bd3): ROLLBACK;
1) should automatically pass transaction
0 passing (36ms)
1 failing
1) DB Model Test
should automatically pass transaction:
TypeError: Class constructor Model cannot be invoked without 'new'
at new User (backend/src/test/ts/transaction.async.mocha.test.ts:73:42)
at /Users/myuser/tmp/test-node-sequelize/backend/src/test/ts/transaction.async.mocha.test.ts:50:20
at step (backend/src/test/ts/transaction.async.mocha.test.ts:51:23)
at Object.next (backend/src/test/ts/transaction.async.mocha.test.ts:32:53)
at /Users/myuser/tmp/test-node-sequelize/backend/src/test/ts/transaction.async.mocha.test.ts:26:71
at Promise (<anonymous>)
at __awaiter (backend/src/test/ts/transaction.async.mocha.test.ts:22:12)
at asyncSaveAndFindTest (backend/src/test/ts/transaction.async.mocha.test.ts:98:20)
at Object.<anonymous> (backend/src/test/ts/transaction.async.mocha.test.ts:39:13)
at step (backend/src/test/ts/transaction.async.mocha.test.ts:51:23)
at Object.next (backend/src/test/ts/transaction.async.mocha.test.ts:32:53)
at /Users/myuser/tmp/test-node-sequelize/backend/src/test/ts/transaction.async.mocha.test.ts:26:71
at Promise (<anonymous>)
at __awaiter (backend/src/test/ts/transaction.async.mocha.test.ts:22:12)
at /Users/myuser/tmp/test-node-sequelize/backend/src/test/ts/transaction.async.mocha.test.ts:37:37
at transaction.prepareEnvironment.then (node_modules/sequelize/lib/sequelize.js:998:21)
at clsBind (node_modules/cls-hooked/context.js:172:17)
at tryCatcher (node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (node_modules/bluebird/js/release/promise.js:693:18)
at Async._drainQueue (node_modules/bluebird/js/release/async.js:133:16)
at Async._drainQueues (node_modules/bluebird/js/release/async.js:143:10)
at Immediate.Async.drainQueues [as _onImmediate] (node_modules/bluebird/js/release/async.js:17:14)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] test-mocha: `mocha --require ts-node/register ./backend/src/test/ts/**/*.mocha.test.ts`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] test-mocha script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/myuser/.npm/_logs/2018-05-10T11_45_46_773Z-debug.log
async function asyncSaveAndFindTest(): Promise<User[]> {
return await new User({ name: 'someName' }).save().then(res => User.findAll());
}
This worries me here, and it might be what is the actual problem. Try separating this into separate lines of code with clear delineations of responsibility.
async function asyncSaveAndFindTest(): Promise<User[]> {
const user: User = new User({ name: 'someName' });
await user.save();
return User.findAll();
}
as I suspect that the parser is not interpreting the order of operations as you'd believe.
Hi, I committed the updated files with multiline and I still have the same error :/
logs:
➜ test-node-sequelize git:(master) npm run-script test-mocha
> [email protected] test-mocha /Users/myuser/dev/myproj/test-node-sequelize
> mocha --require ts-node/register ./backend/src/test/ts/**/*.mocha.test.ts
sequelize deprecated String based operators are now deprecated. Please use Symbol based operators for better security, read more at http://docs.sequelizejs.com/manual/tutorial/querying.html#operators node_modules/sequelize/lib/sequelize.js:242:13
DB Model Test
Executing (default): SELECT 1+1 AS result
Executing (default): CREATE TABLE IF NOT EXISTS `User` (`id` VARCHAR(255) PRIMARY KEY, `name` VARCHAR(255));
Executing (default): PRAGMA INDEX_LIST(`User`)
Executing (default): PRAGMA INDEX_INFO(`sqlite_autoindex_User_1`)
Executing (default): CREATE TABLE IF NOT EXISTS `User` (`id` VARCHAR(255) PRIMARY KEY, `name` VARCHAR(255));
Executing (default): PRAGMA INDEX_LIST(`User`)
Executing (default): PRAGMA INDEX_INFO(`sqlite_autoindex_User_1`)
Executing (1515daac-9d5f-49aa-9449-1c29bf8083e7): BEGIN DEFERRED TRANSACTION;
before add user 1
Executing (1515daac-9d5f-49aa-9449-1c29bf8083e7): ROLLBACK;
1) should automatically pass transaction
0 passing (60ms)
1 failing
1) DB Model Test
should automatically pass transaction:
TypeError: Class constructor Model cannot be invoked without 'new'
at new User (backend/src/test/ts/transaction.async.mocha.test.ts:73:42)
at /Users/myuser/dev/myproj/test-node-sequelize/backend/src/test/ts/transaction.async.mocha.test.ts:50:26
at step (backend/src/test/ts/transaction.async.mocha.test.ts:51:23)
at Object.next (backend/src/test/ts/transaction.async.mocha.test.ts:32:53)
at /Users/myuser/dev/myproj/test-node-sequelize/backend/src/test/ts/transaction.async.mocha.test.ts:26:71
at Promise (<anonymous>)
at __awaiter (backend/src/test/ts/transaction.async.mocha.test.ts:22:12)
at asyncSaveAndFindTest (backend/src/test/ts/transaction.async.mocha.test.ts:98:20)
at Object.<anonymous> (backend/src/test/ts/transaction.async.mocha.test.ts:39:13)
at step (backend/src/test/ts/transaction.async.mocha.test.ts:51:23)
at Object.next (backend/src/test/ts/transaction.async.mocha.test.ts:32:53)
at /Users/myuser/dev/myproj/test-node-sequelize/backend/src/test/ts/transaction.async.mocha.test.ts:26:71
at Promise (<anonymous>)
at __awaiter (backend/src/test/ts/transaction.async.mocha.test.ts:22:12)
at /Users/myuser/dev/myproj/test-node-sequelize/backend/src/test/ts/transaction.async.mocha.test.ts:37:37
at transaction.prepareEnvironment.then (node_modules/sequelize/lib/sequelize.js:998:21)
at clsBind (node_modules/cls-hooked/context.js:172:17)
at tryCatcher (node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (node_modules/bluebird/js/release/promise.js:693:18)
at Async._drainQueue (node_modules/bluebird/js/release/async.js:133:16)
at Async._drainQueues (node_modules/bluebird/js/release/async.js:143:10)
at Immediate.Async.drainQueues [as _onImmediate] (node_modules/bluebird/js/release/async.js:17:14)
updated code:
async function asyncSaveAndFindTest(): Promise<User[]> {
const user: User = new User({ name: 'someName' });
await user.save();
return User.findAll();
}
// async function addUser2(): Promise<User> {
// return await new User({ name: 'someName2' }).save().then(res => {
// return Promise.reject(new Error('simulating exception'));
// });
// }
async function addUser2(): Promise<User> {
const user2 = new User({ name: 'someName2' });
const result = await user2.save();
return result;
}
comitted these changes to here: https://github.com/avidanyum/test-node-sequelize
Your changes aren't pushed, for one. I can't tell where it's throwing.
For two, this style is actually unhelpful - it's a needless "await", and the function itself does not need to be async (since User.findAll() is itself already returning a Promise<User[]>).
Try changing the target to ES2017 in your tsconfig.
changing to ES2017 indeed was the issue!! thank!
It still giving the error
[Node] TypeError: Class constructor Product cannot be invoked without 'new'
[Node] at _loop_1 (node_modules\class-transformer\TransformOperationExecutor.js:114:47)
[Node] at TransformOperationExecutor.transform (node_modules\class-transformer\TransformOperationExecutor.js:178:17)
[Node] at _loop_1 (node_modules\class-transformer\TransformOperationExecutor.js:154:45)
[Node] at TransformOperationExecutor.transform (node_modules\class-transformer\TransformOperationExecutor.js:178:17)
[Node] at _loop_1 (node_modules\class-transformer\TransformOperationExecutor.js:154:45)
[Node] at TransformOperationExecutor.transform (node_modules\class-transformer\TransformOperationExecutor.js:178:17)
[Node] at _loop_1 (node_modules\class-transformer\TransformOperationExecutor.js:154:45)
[Node] at TransformOperationExecutor.transform (node_modules\class-transformer\TransformOperationExecutor.js:178:17)
[Node] at _loop_1 (node_modules\class-transformer\TransformOperationExecutor.js:154:45)
[Node] at TransformOperationExecutor.transform (node_modules\class-transformer\TransformOperationExecutor.js:178:17)
[Node] at node_modules\class-transformer\TransformOperationExecutor.js:33:41
[Node] at Array.forEach (<anonymous>)
[Node] at TransformOperationExecutor.transform (node_modules\class-transformer\TransformOperationExecutor.js:30:19)
[Node] at _loop_1 (node_modules\class-transformer\TransformOperationExecutor.js:154:45)
[Node] at TransformOperationExecutor.transform (node_modules\class-transformer\TransformOperationExecutor.js:178:17)
[Node] at _loop_1 (node_modules\class-transformer\TransformOperationExecutor.js:154:45)
[Node] at TransformOperationExecutor.transform (node_modules\class-transformer\TransformOperationExecutor.js:178:17)
[Node] at ClassTransformer.classToPlain (node_modules\class-transformer\ClassTransformer.js:9:25)
[Node] at Object.classToPlain (node_modules\class-transformer\index.js:12:29)
[Node] at ExpressDriver.BaseDriver.transformResult (node_modules\routing-controllers\driver\BaseDriver.js:33:42)
[Node] at ExpressDriver.handleSuccess (node_modules\routing-controllers\driver\express\ExpressDriver.js:225:23)
[Node] at node_modules\routing-controllers\RoutingControllers.js:128:61
[Node] GET /products 500 81.439 ms - -
{
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"target": "ES2017",
"noImplicitAny": true,
"moduleResolution": "node",
"sourceMap": true,
"declaration": true,
"strictNullChecks": true,
"noUnusedLocals": true,
"pretty": true,
"skipLibCheck": true,
"outDir": "dist",
"baseUrl": ".",
"paths": {
"*": [
"node_modules/*",
"src/types/*"
]
}
},
"exclude": [
"node_modules"
],
"include": [
"src/**/*"
]
}
@rochapablo looks like someone is having the same issue as you here: https://github.com/typestack/class-transformer/issues/242
Most helpful comment
Try changing the target to
ES2017in your tsconfig.