I'm working on a REST API for the backend of a simple e-commerce app using Node JS, PostgreSQL and Sequelize, and I'm facing an issue with Sequelize when I try to add a product to the shopping cart. It returns an error "column Nan does not exist"
Initially I was using Integer for the user Id as the primary key, then I changed for UUID to better suit the purpose.
The code I'm using for the models and migrations is the following:
//User model export default (sequelize, DataTypes) => { const User = sequelize.define( 'User', { id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, allowNull: false, primaryKey: true, unique: true, }, name: { type: DataTypes.STRING, allowNull: false }, password: { type: DataTypes.STRING, allowNull: false }, email: { type: DataTypes.STRING, allowNull: false, unique: { name: 'user_email', msg: 'A user with this email already exists.' } }, }, User.associate = models => { User.hasOne(models.Cart, { foreignKey: 'userId', as: 'cart', onDelete: 'cascade' }); }; User.associate = models => { User.hasMany(models.Order, { foreignKey: 'userId', as: 'orders', onDelete: 'cascade' }); }; return User; }; //User migration export const up = (queryInterface, Sequelize) => queryInterface.createTable('Users', { id: { type: Sequelize.UUID, defaultValue: Sequelize.UUIDV4, allowNull: false, primaryKey: true, unique: true, }, name: { allowNull: false, type: Sequelize.STRING }, password: Sequelize.STRING, email: { allowNull: false, type: Sequelize.STRING, unique: true }, createdAt: { allowNull: false, type: Sequelize.DATE, defaultValue: Sequelize.fn('now') }, updatedAt: { allowNull: false, type: Sequelize.DATE, defaultValue: Sequelize.fn('now') }, }); export const down = queryInterface => queryInterface.dropTable('Users'); Cart model
export default (sequelize, DataTypes) => { const Cart = sequelize.define('Cart', { id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, allowNull: false, primaryKey: true, }, userId: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, allowNull: false }, cartItem: { type: DataTypes.TEXT, allowNull: false, get(value) { return JSON.parse(this.getDataValue(value)); }, set(value) { this.setDataValue('cartItem', JSON.stringify(value)); } } }); Cart.associate = models => { Cart.belongsTo(models.User, { foreignKey: 'userId', as: 'owner' }); }; return Cart; }; Cart migration
export const up = (queryInterface, Sequelize) => queryInterface.createTable('Carts', { id: { allowNull: false, primaryKey: true, type: Sequelize.UUID, defaultValue: Sequelize.UUIDV4, }, userId: { type: Sequelize.UUID, defaultValue: Sequelize.UUIDV4, allowNull: false }, cartItem: { type: Sequelize.TEXT, allowNull: false }, createdAt: { allowNull: false, type: Sequelize.DATE, defaultValue: Sequelize.fn('now') }, updatedAt: { allowNull: false, type: Sequelize.DATE, defaultValue: Sequelize.fn('now') } }); export const down = queryInterface => queryInterface.dropTable('Carts'); Code to handle the add to cart:
addToCart() { return this.asyncWrapper(async (req, res) => { const { body, user } = req; body.userId = user.id; const cart = await this.service.addToCart(body); this.sendResponse(res, cart, undefined, 201); }); } Add to cart service
async cart(userId, options = {}) { const cart = await super.find({ userId }, options); return cart; } async addToCart(data, options) { const { userId, productId, qty } = data; const [result] = await this.model.findOrCreate({ where: { userId: +userId }, defaults: { cartItem: new CartItem() } }); const cartData = JSON.parse(result.dataValues.cartItem); const cartItem = new CartItem(cartData); const product = await ProductService.getById(productId, { plain: true }); ExceptionHandler.throwErrorIfNull(product); const cart = cartItem.addToCart(product, qty); result.cartItem = cart; result.save(); return result; } The SQL query generated by Sequelize is the following:
SELECT "id","userId","cartItem","createdAt","updatedAt" FROM "Carts" AS "Cart" WHERE "Cart"."userId" = NaN LIMIT 1;
The goal is to use UUID as primary key in the database. This issue started when I changed the Datatype from Integer for UUID and I can't see what is wrong with the code.
Any advice on how to solve this?
Sequelize version: "^5.21.9" with "pg": "^8.2.0" and "pg-hstore": "^2.3.3".
addToCart() { return this.asyncWrapper(async (req, res) => { const { body, user } = req; body.userId = user.id; const cart = await this.service.addToCart(body); this.sendResponse(res, cart, undefined, 201); }); }this.service.addToCartcode. And please add it to your post and not as a comment hereuniqueanddefaultValueoptions in PK field inUsermodel because it's already a primary key (that means unique) and its default value is generated by DB. Also you need to indicateautoIncrement: truein PK field in model so Sequelize knows that a default value whould be generated by DBautoIncrement: truedoesn't work since I'm using UUID identifier