sequelize: "result.get is not a function" when querying with global raw: true and includes
Hi guys! I encountered a problem, when trying to do includes. I have already saw a couple of similar issues here, but not equal to mine. The case is simpliest - users and roles. Here are the models:
const UserScheme = require('server/dataAccess/schemes/userScheme');
module.exports = function (sequelize, DataTypes) {
const UserDataModel = sequelize.define(UserScheme.tableName, UserScheme.columnsDescription, {
schema: UserScheme.schema
});
return UserDataModel;
};
const UserScheme = require('server/dataAccess/schemes/userScheme');
const UserRoleScheme = require('server/dataAccess/schemes/userRoleScheme');
const UserRoleAssociationScheme = require('server/dataAccess/schemes/userRoleAssociationScheme');
module.exports = function (sequelize, DataTypes) {
const UserRoleDataModel = sequelize.define(UserRoleScheme.tableName, UserRoleScheme.columnsDescription, {
schema: UserRoleScheme.schema,
classMethods: {
associate: models => {
models[UserRoleScheme.tableName].belongsToMany(models[UserScheme.tableName], {
as: 'Users',
through: UserRoleAssociationScheme.tableName,
foreignKey: {
name: UserRoleAssociationScheme.columnsDescription.userRoleId.field
}
});
models[UserScheme.tableName].belongsToMany(models[UserRoleScheme.tableName], {
as: 'Roles',
through: UserRoleAssociationScheme.tableName,
foreignKey: {
name: UserRoleAssociationScheme.columnsDescription.userInfoId.field
}
});
}
}
});
return UserRoleDataModel;
};
And here are the schemas:
const Sequelize = require('sequelize');
class UserDataScheme extends BaseInternalScheme {
constructor(dataTypes) {
super(dataTypes);
this.defineTable('userInfo');
this.defineColumns({
id: {
type: Sequelize.UUID,
field: 'id',
allowNull: false,
unique: true,
primaryKey: true
},
createdAt: {
type: Sequelize.DATE,
field: 'createdAt'
},
updatedAt: {
type: Sequelize.DATE,
field: 'updatedAt'
},
fullName: {
type: Sequelize.STRING,
field: 'fullName',
allowNull: false,
validate: {
notEmpty: true,
len: [0, 255]
}
},
firstName: {
type: Sequelize.STRING,
field: 'firstName',
allowNull: false,
validate: {
notEmpty: true,
len: [0, 255]
}
},
lastName: {
type: Sequelize.STRING,
field: 'lastName',
allowNull: false,
validate: {
notEmpty: true,
len: [0, 255]
}
},
phone: {
type: Sequelize.STRING,
field: 'phone',
allowNull: false,
validate: {
notEmpty: true,
len: [0, 255]
}
}
});
}
}
module.exports = new UserDataScheme();
const BaseInternalScheme = require('server/dataAccess/schemes/baseInternalScheme');
const Sequelize = require('sequelize');
class UserRoleScheme extends BaseInternalScheme {
constructor() {
super();
this.defineTable('userRole');
this.defineColumns({
id: {
type: Sequelize.UUID,
field: 'id',
allowNull: false,
unique: true,
primaryKey: true
},
createdAt: {
type: Sequelize.DATE,
field: 'createdAt'
},
updatedAt: {
type: Sequelize.DATE,
field: 'updatedAt'
},
name: {
type: Sequelize.STRING,
field: 'name',
allowNull: false,
validate: {
notEmpty: true,
len: [0, 255]
}
}
});
}
}
module.exports = new UserRoleScheme();
const BaseScheme = require('server/dataAccess/schemes/baseScheme');
const Sequelize = require('sequelize');
class UserRoleAssociationScheme extends BaseScheme {
constructor() {
super('public');
this.defineTable('userRoleAssociation');
this.defineColumns({
id: {
type: Sequelize.UUID,
field: 'id',
allowNull: false,
unique: true,
primaryKey: true
},
createdAt: {
type: Sequelize.DATE,
field: 'createdAt'
},
updatedAt: {
type: Sequelize.DATE,
field: 'updatedAt'
},
userInfoId: {
type: Sequelize.UUID,
allowNull: false,
field: 'userInfoId'
},
userRoleId: {
type: Sequelize.UUID,
allowNull: false,
field: 'userRoleId'
},
createdAt: {
type: Sequelize.DATE,
field: 'createdAt'
},
updatedAt: {
type: Sequelize.DATE,
field: 'updatedAt'
}
});
}
}
module.exports = new UserRoleAssociationScheme();
The problem is in the code below:
return this._users.findOne({
attributes: userAttributes, // Some list of attributes
where: { id },
include: {
as: 'Roles',
attributes: [UserRoleScheme.columnsDescription.id.field],
model: this._roles, //this._roles is realy a userRole model
}
});
What is expected?
I expect that code will query user with necessary id and join the information about his roles.
What is actually happening?
Our logger shows the query generated, and when we execute it in the postgres it works fine, but in the application the sequelize throws an error and I haven’t found any information about it.
error: TypeError: result.get is not a function
at sequelize\lib\model.js:1424:37
at Array.reduce (native)
at sequelize\lib\model.js:1423:17
at tryCatcher (\sequelize\node_modules\bluebird\js\release\util.js:16:23)
at MappingPromiseArray._promiseFulfilled (sequelize\node_modules\bluebird\js\release\map.js:57:38)
at MappingPromiseArray.PromiseArray._iterate (sequelize\node_modules\bluebird\js\release\promise_array.js:113:31)
at MappingPromiseArray.init (\sequelize\node_modules\bluebird\js\release\promise_array.js:77:10)
at new MappingPromiseArray (sequelize\node_modules\bluebird\js\release\map.js:25:10)
at map (sequelize\node_modules\bluebird\js\release\map.js:152:12)
at Function.Promise.map (sequelize\node_modules\bluebird\js\release\map.js:160:12)
This is the problematic code:
...
return Model.$findSeparate(
results.reduce(function (memo, result) {
var associations = result.get(include.association.as); <- The error
// Might be an empty belongsTo relation
if (!associations) return memo;
...
I have already saw that message when we were trying to follow custom approach in model defining and in that case includes not worked at all, but we got rid of it and followed the approach described in the docs when working with Node and Express.
Maybe I am misunderstood something or there is some error in the model definition, please help me to solve it 😃
Dialect:_ postgres __Database version: 9.5 Sequelize version: “^3.23.3”
About this issue
- Original URL
- State: open
- Created 8 years ago
- Reactions: 7
- Comments: 22 (5 by maintainers)
Thanks Felix!
Maybe it’s a good idea to change the title in order to make it clear that
raw: true
should be set into global settings of sequelize to replicate the issue.Using
raw: true
directly in the query works just fine.I found out that even simplest includes stopped working. Actually, it’s not necessary, we have found out the root of the problem - the raw option. When you create a sequelize instance and pass as the option raw: true (migrated from mongo for us), in all includes sequelize throw an error in the row:
However, if you pass raw: true into the query itself, the result would be as expected - plain object. So we got rid of global raw: true and put it into our queries. Hope it will help you to improve sequelize 😃 Good luck!