Skip to content

Non-static update method of the Models returns old value #612

Open
@BjarkeNL

Description

@BjarkeNL

Hi! This library looks like really cool - this is a much better way to declare model-classes for sequelize! Unfortunately i ran into a problem when trying it out:

Versions

I'm submitting a ...
[x] bug report
[ ] feature request

Actual behavior:

I tried converting my existing sequelize code to sequelize-typescript. It worked for the most part but i encountered a difference in behavior.
(Not 100% how to debug this, so i am reporting it as a bug here - could of course be a configuration issue or similar on my end)

The non-static update-function on a Model, normally returns a promise containing a model-object with the updated property values. After changing from plain sequelize to sequelize-typescript, it no longer does this - instead the promise now contains a model-object with the old values from before the update.
(The database is updated with the new values, the problem is just that the return value of the update-method contains different values than it normally does)

When debugging, i can see that the dataValues-object of the model-object are updated with the new values, but the properties of the model-object still contain the old values. (They are not updated)

The same problem happens for the with set + save combo.

Expected behavior:

The non-static update method should return a model-object with updated values, like in plain sequelize. (and same for set+save)

Steps to reproduce:
See code below

Related code:

The model:

import {Table, Column, Model, HasMany, DataType, BelongsTo, BeforeDestroy, DeletedAt, UpdatedAt, CreatedAt} from 'sequelize-typescript';

@Table({
    tableName: 'users',
    timestamps: true,
    underscored: true,
    paranoid: true
})
export default class User extends Model<User> {

    @Column({type: DataType.INTEGER, field: "id", primaryKey: true, autoIncrement:true})
    id: number = this.id; // <- see: https://github.com/sequelize/sequelize/issues/10579  https://github.com/babel/babel/issues/9105
       
    @Column({type: DataType.STRING(100), field: "first_name", allowNull: false})
    firstName: string = this.firstName;
}

The code to reproduce the problem:

...

const user = await User.findById(userId, { transaction: t });

console.log("Before update: ", user.firstName); // the old value

const updatedUser = await user.update({ firstName: "Something" }, { transaction: t });

console.log("After update: ", updatedUser.firstName); // still the old value

...

Same problem happens with:

...

const user = await User.findById(userId, { transaction: t });

console.log("Before update: ", user.firstName); // the old value

user.set({ firstName: "Something" });

console.log("After set: ", user.firstName); // still the old value

const updatedUser = await user.save({ transaction: t });	

console.log("After save: ", user.firstName); // still the old value
console.log("After save: ", updatedUser.firstName); // still the old value

...

Without sequelize-typescript (i.e. with just plain sequelize without typescript), it works.

It is of course not impossible that it is a babel vs typescript issue.
Could it, for example, be because i'm assigning each property to itself in the model? (for the reason for doing this, see: sequelize/sequelize#10579 and babel/babel#9105 ).

Library configurations:

.babelrc:

{
    "presets": [
	["@babel/env", {"targets": {"node": "8.0"}}],
	"@babel/react",
	["@babel/typescript", {"isTSX": true, "allExtensions": true}]
    ],
    "plugins": [
	["@babel/plugin-proposal-decorators", { "legacy": true }],
	["@babel/plugin-proposal-class-properties", { "loose":  true }]
    ]
}

tsconfig.json:

{
    "compilerOptions": {
	"target": "esnext",
	"moduleResolution": "node",
	"allowJs": true,
	"noEmit": true,
	"strict": true,
	"isolatedModules": true,
	"esModuleInterop": true,

	"jsx": "react",

	"experimentalDecorators": true,  // for sequelize-typescript
	"emitDecoratorMetadata": true   // for sequelize-typescript
    },
    "include": [
	"./src/"
    ]
}

Sequelize-typesctipt setup:

import config from ...;
import {Sequelize} from 'sequelize-typescript';

const sequelize = new Sequelize({
    database: config.db.database,
    username: config.db.username,
    password: config.db.password,
    host: config.db.host,
    port: config.db.port,
    dialect: "mysql",
    pool: {
	max: 100,
	min: 0,
	idle: 1000000
    },
    define: {
	charset: 'utf8mb4',
	collate: 'utf8mb4_unicode_ci',
	timestamps: true
    },
    logging: config.sequelize_logging ? (x: any) => console.log("[SEQUELIZE]",x) : () => false,
    typeValidation:false,
    modelPaths: [__dirname + "/../entities"]
});


sequelize
    .authenticate()
    .catch(err => {
	console.error('Unable to connect to the database:', err);
    });

sequelize.sync({
    force: false
});

export default sequelize;
insert short code snippets here

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions