Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sequelize object is empty #532

Open
3 of 9 tasks
LBeckX opened this issue Feb 10, 2023 · 4 comments
Open
3 of 9 tasks

Sequelize object is empty #532

LBeckX opened this issue Feb 10, 2023 · 4 comments
Labels
bug Something isn't working

Comments

@LBeckX
Copy link

LBeckX commented Feb 10, 2023

Is there an existing issue for this?

  • I have searched the existing issues

Describe the issue

Sequelize map is empty

Models/DTOs/VMs

export class User extends Model {
}

User.init({
    id: {
        type: DataTypes.INTEGER,
        autoIncrement: true,
        allowNull: false,
        primaryKey: true,
        validate: {
            isNumeric: true
        }
    },
    username: {
        type: DataTypes.STRING,
        allowNull: false,
        validate: {
            len: [5, 20]
        }
    },
    email: {
        type: DataTypes.STRING,
        allowNull: false,
        unique: true,
        validate: {
            isEmail: true
        }
    },
    password: {
        type: DataTypes.STRING,
        allowNull: true,
    }
}, {
    tableName: 'User',
    sequelize
});

export class UserResponseDto {
    @AutoMap()
    username: string;

    @AutoMap()
    email: string;
}

export const mapper = createMapper({
    strategyInitializer: sequelize(),
});

createMap(mapper, UserEntity, UserResponseDto);

const userResponse = await UserEntity.findByPk(1);

console.log(mapper.map(userResponse .get(), User, UserResponseDto))

Mapping configuration

No response

Steps to reproduce

npm i @automapper/core @automapper/classes @automapper/sequelize

Expected behavior

{
  username: 'MY-USER',
  email: '[email protected]'
}

Screenshots

No response

Minimum reproduction code

No response

Package

  • I don't know.
  • @automapper/core
  • @automapper/classes
  • @automapper/nestjs
  • @automapper/pojos
  • @automapper/mikro
  • @automapper/sequelize
  • Other (see below)

Other package and its version

No response

AutoMapper version

8.7.7

Additional context

Node: v18.14.0

"@automapper/classes": "^8.7.7",
"@automapper/core": "^8.7.7",
"@automapper/sequelize": "^8.7.7",
"bcrypt": "^5.1.0",
"body-parser": "^1.20.1",
"cors": "^2.8.5",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"helmet": "^6.0.1",
"joi": "^17.7.0",
"mariadb": "^3.0.2",
"morgan": "^1.10.0",
"multer": "^1.4.5-lts.1",
"reflect-metadata": "^0.1.13",
"sequelize": "^6.28.0"
@LBeckX LBeckX added the bug Something isn't working label Feb 10, 2023
@spuxx1701
Copy link

spuxx1701 commented Oct 26, 2024

@LBeckX did you ever happen to find a solution?

Edit: Should anyone be in dire need of a mapping functionality that works with sequelize, I implemented one myself here:
https://github.com/spuxx1701/jslibs/tree/main/packages/nest-utils/src/mapping

It's very simple and easy to extend with more features. Feel free to copy.

@LBeckX
Copy link
Author

LBeckX commented Oct 28, 2024

@spuxx1701
As I remember, I used the following solutions for the problems.

Install https://github.com/typestack/class-transformer

Create the user entity

User.init({
    id: {
        type: DataTypes.INTEGER,
        autoIncrement: true,
        allowNull: false,
        primaryKey: true,
        validate: {
            isNumeric: true
        }
    },
    username: {
        type: DataTypes.STRING,
        allowNull: false,
        validate: {
            len: [5, 20]
        }
    },
    email: {
        type: DataTypes.STRING,
        allowNull: false,
        unique: true,
        validate: {
            isEmail: true
        }
    },
    password: {
        type: DataTypes.STRING,
        allowNull: true,
    }
}, {
    tableName: 'User',
    sequelize
});

Create a UserDto

export class UserDto {
    @Expose()
    id: number;
    
    @Expose()
    username: string;
}

Create a helper function

export const getUserDto = (obj: any) => plainToInstance(UserDto , obj, {excludeExtraneousValues: true})

It also works with arrays or child entities

@spuxx1701
Copy link

@LBeckX Thanks for letting me know! I'll take a look at your solution. Utilizing class-transformer sounds like a good approach since it's commonly part of the nestjs app stack anyways. 🎉

@LBeckX
Copy link
Author

LBeckX commented Oct 28, 2024

If you use nestjs, I can recommend this article from the documentation.

https://docs.nestjs.com/interceptors

My code to transform all outgoing entites:

transform.interceptor.ts

import {
  CallHandler,
  ExecutionContext,
  Injectable,
  NestInterceptor,
} from '@nestjs/common';
import { map, Observable } from 'rxjs';
import { instanceToPlain } from 'class-transformer';

@Injectable()
export class TransformInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(map((data) => instanceToPlain(data)));
  }
}

app.module.ts

...
providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: TransformInterceptor,
    },
  ],
...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants