Issue with create function inside Loopback framework - node.js

I have this model
import {Entity, model, property} from '#loopback/repository';
#model()
export class Coupon extends Entity {
#property({
id: true,
type: 'string',
required: false,
mongo: {
columnName: '_id',
dataType: 'ObjectID',
},
})
id: string;
#property({
type: 'string',
required: true,
})
name: string;
#property({
type: 'number',
required: true,
})
maximumUses: number;
#property({
type: 'string',
required: true,
})
type: string;
#property({
type: 'number',
required: true,
})
amount: number;
#property({
type: 'number',
required: true,
})
maximumUsesPerPerson: number;
#property({
type: 'string',
required: true,
})
validFrom: string;
#property({
type: 'string',
required: true,
})
validTo: string;
#property({
type: 'number',
required: true,
})
currentTotalUses: number;
#property({
type: 'array',
itemType: 'string',
})
certainDays?: string[];
#property({
type: 'array',
itemType: 'string',
})
certainHours?: string[];
#property({
type: 'boolean',
required: true,
})
valid: boolean;
#property({
type: 'array',
itemType: 'string',
})
clients?: string[];
#property({
type: 'disabled',
required: true,
})
disabled: boolean;
constructor(data?: Partial<Coupon>) {
super(data);
}
}
repository for the model
import {DefaultCrudRepository} from '#loopback/repository';
import {Coupon} from '../models';
import {TestDataSource} from '../datasources';
import {inject} from '#loopback/core';
export class CouponRepository extends DefaultCrudRepository<
Coupon,
typeof Coupon.prototype.id
> {
constructor(
#inject('datasources.test') dataSource: TestDataSource,
) {
super(Coupon, dataSource);
}
}
now the following function should works well
await this.couponsRepo.create({ name: 'string',
maximumUses: 0,
maximumUsesPerPerson: 0,
amount: 0,
validFrom: 'string',
validTo: 'string',
type: 'percentage',
valid: true,
currentTotalUses: 0,
disabled: false });
but it fires this error
ReferenceError: g is not defined
at new disabled (eval at createModelClassCtor (../LBIssue/lbissue/node_modules/loopback-datasource-juggler/lib/model-builder.js:678:21), :10:27)
to simply produce this error , create empty loopback 4 project
then put the coupon model = with the code I provided

There is an error in your model definition.
See this
#property({
type: 'disabled',
required: true,
})
disabled: boolean;
type cannot be disabled. It should be
#property({
type: 'boolean',
required: true,
})
disabled: boolean;

Related

Creation of duplicate IDs in arrays of different documents in mongo db

I want to add an element to the array of all collections in the city collection, but Mongo creates the ID as duplicate.
this is my code
await this.cityRepository.updateMany(
{},
{
$push: {
tags: {
title: tagValue.title,
description: tagValue.description,
applyToAllCity: tagValue.cityId ? false : true,
},
},
},
);
City Schema
export class BaseCity extends Document {
#Prop({
type: String,
required: true,
})
_id: string;
#Prop({ type: String, unique: true })
code: string;
#Prop({ type: String, ref: Province.name })
province: string | Province;
#Prop({ type: String })
faName: string;
}
#Schema({ timestamps: true })
#Schema({ collection: 'city', virtuals: true, _id: false, timestamps: true })
export class City extends BaseCity {
#Prop({ type: String })
imageName: string;
#Prop({ index: true, type: String })
enName: string;
#Prop({ type: Number })
displayOrder: number;
#Prop({ type: Boolean })
isFeatured: boolean;
#Prop({ type: Boolean })
isEnabled: boolean;
#Prop({ type: Coordinate })
coordinate: Coordinate;
#Prop([{ type: Region, ref: Region.name, default: [] }])
region: Region[];
#Prop([{ type: SubMenu }])
subMenu: SubMenu[];
#Prop([{ type: CityTags }])
tags: CityTags[];
}
const CitySchema = SchemaFactory.createForClass(City);
CitySchema.index({ faName: 'text' });
export { CitySchema };
DB
As you can see, ID 63ec8f47efbd82c8face341a is duplicated in all documents.
Is there a solution to solve this problem?
To avoid duplicate IDs, you could use the $addToSet instead of $push. The $addToSet adds an element to an array only if it does not already exist in the set.
Check this:
await this.cityRepository.updateMany(
{},
{
$addToSet: {
tags: {
title: tagValue.title,
description: tagValue.description,
applyToAllCity: tagValue.cityId ? false : true,
},
},
},
);
Update:
To keep unique ids
await this.cityRepository.updateMany(
{},
{
$push: {
tags: {
_id: new ObjectId(),
title: tagValue.title,
description: tagValue.description,
applyToAllCity: tagValue.cityId ? false : true,
},
},
},
);

Why am I getting a validation error? Nestjs, Sequelize , PostgressQL

I want to create a dependency where one User can have many InvestorCase, but one InvestorCase belongs to only one User. I need to have user_id field in InvestorCase.
User entity:
import { InvestorCase } from 'src/investor-case/entities/investor-case.entity';
import { ApiProperty } from '#nestjs/swagger';
import { Exclude } from 'class-transformer';
import {
AllowNull,
Column,
DataType,
Default,
HasMany,
IsIn,
Model,
Table,
} from 'sequelize-typescript';
import { UserRole, UserStatus } from 'src/shared/enums';
import { IUser } from 'src/shared/interfaces';
const userRoleValues = Object.values(UserRole);
const userStatusValues = Object.values(UserStatus);
#Table({ tableName: 'user' })
export class User extends Model<User, IUser> {
#ApiProperty({ example: '1', description: 'User`s Id' })
#Column({
type: DataType.INTEGER,
unique: true,
autoIncrement: true,
primaryKey: true,
})
public id: number;
#ApiProperty({ example: 'test#gmail.com', description: 'User`s Email' })
#Column({
type: DataType.STRING,
allowNull: false,
})
public email: string;
#ApiProperty({ example: 'password', description: 'User``s password' })
#Column({
type: DataType.STRING,
allowNull: true,
})
#Exclude()
public password: string;
#ApiProperty({ example: 'Barak', description: 'User`s name' })
#Column({
type: DataType.STRING,
allowNull: false,
})
public firstName: string;
#ApiProperty({ example: 'Obama', description: 'User`s surname' })
#Column({
type: DataType.STRING,
allowNull: false,
})
public lastName: string;
#ApiProperty({ example: '3806799599432', description: 'User`s phone number' })
#Column({
type: DataType.STRING,
})
public phoneNumber: string;
#ApiProperty({ example: 'verified', description: 'Account status' })
#IsIn({
args: [userStatusValues],
msg: `User status must one of the following:
${userStatusValues.join(', ')}`,
})
#Default(UserStatus.UNVERIFIED)
#Column
public status: UserStatus;
#ApiProperty({
example: 'developer',
description: 'User`s role',
enum: UserRole,
})
#IsIn({
args: [userRoleValues],
msg: `User role must one of the following:
${userRoleValues.join(', ')}`,
})
#Default(UserRole.INVESTOR)
#AllowNull(false)
#Column
public role: UserRole;
#HasMany(() => InvestorCase)
investorCases: InvestorCase[];
}
InvestorCare entity:
import { ApiProperty } from "#nestjs/swagger";
import { BelongsTo, Column, DataType, ForeignKey, IsIn, Model, PrimaryKey, Table } from "sequelize-typescript";
import { PaymentMethods } from 'src/shared/enums'
import { IInvestorCase } from 'src/shared/interfaces';
import { User } from "src/user/entities/user.entity";
const paymentMethods = Object.values(PaymentMethods);
#Table({ tableName: 'investor-case' })
export class InvestorCase extends Model<InvestorCase, IInvestorCase> {
#ApiProperty({ example: '1', description: 'Unique ID' })
#PrimaryKey
#Column({ type: DataType.INTEGER, unique: true, autoIncrement: true })
public id: number;
#ApiProperty({ example: '10000', description: 'The amount the investor will deposit initially.' })
#Column({ type: DataType.INTEGER, unique: true, allowNull: false, validate: { min: 1000 } })
public initialPayment: number;
#ApiProperty({ example: '1000', description: 'The amount that the investor will contribute monthly.' })
#Column({ type: DataType.INTEGER, allowNull: true, validate: { min: 500 } })
public monthlyPayment: number;
#ApiProperty({
example: 'true',
description: 'The payment method by which the investments will be made.',
enum: paymentMethods
})
#IsIn({
args: [paymentMethods],
msg: `The payment method must one of the following: ${paymentMethods.join(',')}`
})
#Column({ type: DataType.STRING, allowNull: false, defaultValue: PaymentMethods.Manually })
public paymentMethod: string;
#BelongsTo(() => User, {
foreignKey: 'userId',
as: 'UserId',
})
#ApiProperty({
example: '1',
description: 'Company representative user id',
})
#ForeignKey(() => User)
#Column({ type: DataType.INTEGER })
userId: number;
}
I try to create InvestorCase using this:
{
"initialPayment": 5000,
"monthlyPayment": 1000,
"paymentMethod": "Link a bank account",
"userId": 2
}
[Nest] 244 - 05/10/2022, 10:30:26 AM ERROR [ExceptionsHandler] Validation error
Error:
at Query.run (/app/node_modules/sequelize/src/dialects/postgres/query.js:76:25)
at /app/node_modules/sequelize/src/sequelize.js:643:28
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at PostgresQueryInterface.insert (/app/node_modules/sequelize/src/dialects/abstract/query-interface.js:773:21)
at InvestorCase.save (/app/node_modules/sequelize/src/model.js:4046:35)
at Function.create (/app/node_modules/sequelize/src/model.js:2253:12)
at InvestorCaseService.create (/app/src/investor-case/investor-case.service.ts:18:16)
at InvestorCaseController.create (/app/src/investor-case/investor-case.controller.ts:18:16)
at /app/node_modules/#nestjs/core/router/router-execution-context.js:46:28
at /app/node_modules/#nestjs/core/router/router-proxy.js:9:17
But alwways got error:
[Nest] 244 - 05/10/2022, 10:30:26 AM ERROR [ExceptionsHandler] Validation error
Error:
at Query.run (/app/node_modules/sequelize/src/dialects/postgres/query.js:76:25)
at /app/node_modules/sequelize/src/sequelize.js:643:28
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at PostgresQueryInterface.insert (/app/node_modules/sequelize/src/dialects/abstract/query-interface.js:773:21)
at InvestorCase.save (/app/node_modules/sequelize/src/model.js:4046:35)
at Function.create (/app/node_modules/sequelize/src/model.js:2253:12)
at InvestorCaseService.create (/app/src/investor-case/investor-case.service.ts:18:16)
at InvestorCaseController.create (/app/src/investor-case/investor-case.controller.ts:18:16)
at /app/node_modules/#nestjs/core/router/router-execution-context.js:46:28
at /app/node_modules/#nestjs/core/router/router-proxy.js:9:17

How to seed data in NestJs & Mongoose?

I've shops and products collections in Mongodb.
Shops Schema
#Schema({ timestamps: true })
export class Shop extends Document {
#Prop({ required: true, index: { unique: true } })
id: string;
#Prop({ required: true, index: { unique: true } })
shop: string;
#Prop({ required: true })
accessToken: string;
#Prop({ required: true })
scope: string;
#Prop({ type: Date })
expires: Date;
#Prop({ type: Boolean })
isOnline: boolean;
#Prop({ type: String })
state: string;
}
export const ShopSchema = SchemaFactory.createForClass(Shop);
Products Schema
#Schema({ timestamps: true })
export class Product extends Document {
#Prop({ required: true, index: {unique: true} })
id: string
#Prop({ required: true })
title: string
#Prop({ required: true })
desc: string
#Prop({ required: true })
price: number
#Prop({ required: true })
stock: number
#Prop({ type: mongooseSchema.Types.ObjectId, ref: 'Shop', required: true })
shopId: mongooseSchema.Types.ObjectId;
}
export const ProductSchema = SchemaFactory.createForClass(Product);
Now I want to seed some dummy data (from json) into products collection whenever new shop is added. I've done using Nestjs Command and it worked perfectly. But I don't want to seed data by using command, so I tried on Nestjs lifecycle event method (which is not a proper way to do). Can anyone recommend me any other method?
I heard we can do using Mongoose hooks. If we can, please anyone explain about it.

How to relate in sequelize

I am trying to relate my Users model with the Posts model, what I want to do is that the user when creating a post saves the post id in the 'posteds' field of the user model, but I can't do it
Post Table:
'posteds' shouldn't be there, it should be in the users table
My relationships:
Users.hasMany(Posts, {foreignKey: 'posteds'})
Posts.belongsTo(Users, {foreignKey : 'userId'})
Model User:
import { DataTypes, UUIDV4, Optional, Model} from "sequelize"
import { connection } from "../database"
import { hash, genSalt, compare } from "bcryptjs";
import Posts from "./posts.model";
export const rolesEnum: string[] = ['ADMIN_ROLE', 'MODERATOR_ROLE','USER_ROLE']
interface UserAttributes{
id: number,
email: string,
password: string,
img_url: string,
role: 'ADMIN_ROLE' | 'MODERATOR_ROLE' | 'USER_ROLE',
created_at: Date,
updated_at?: Date
}
interface UserCreationAttributes extends Optional<UserAttributes, "id" | "created_at" | 'img_url'> {}
// We need to declare an interface for our model that is basically what our class would be
interface UserInstance
extends Model<UserAttributes, UserCreationAttributes>,
UserAttributes {}
const Users = connection.define<UserInstance>('users', {
id: {
type: DataTypes.UUID,
primaryKey: true,
defaultValue: UUIDV4,
unique: true,
allowNull: false
},
email: {
type: DataTypes.STRING,
unique: true,
allowNull: false
},
password: {
type: DataTypes.STRING,
allowNull: false
},
img_url: {
type: DataTypes.STRING,
defaultValue: process.env.DEFAULT_IMAGE || 'default.svg',
allowNull: false
},
role: {
type: DataTypes.STRING,
values: rolesEnum,
defaultValue: 'USER_ROLE',
allowNull: false
},
created_at: {
type: DataTypes.DATE,
defaultValue: DataTypes.NOW,
allowNull: false
},
updated_at: {
type: DataTypes.DATE,
defaultValue: DataTypes.NOW,
}
},{
timestamps: false
})
export default Users
Model Posts:
import { DataTypes, Optional, Model, UUIDV4} from "sequelize";
import {connection} from "../database";
interface PostAttributes {
id: number,
title: string,
description: string,
categorys?: Array<string>,
img_url: string,
created_at: Date,
updated_at?: Date,
userId?: string;
}
interface PostCreationAttributes extends Optional<PostAttributes, "id" | "created_at" |"img_url" | "categorys"> {}
// We need to declare an interface for our model that is basically what our class would be
interface PostInstance
extends Model<PostAttributes, PostCreationAttributes>,
PostAttributes {}
const Posts = connection.define<PostInstance>('posts', {
id: {
type: DataTypes.UUID,
primaryKey: true,
defaultValue: UUIDV4,
unique: true
},
title: {
type: DataTypes.STRING,
allowNull: false
},
description: {
type: DataTypes.STRING,
allowNull: false
},
categorys: {
type: DataTypes.ARRAY(DataTypes.ENUM('web-devlopment', 'recent', 'featured')),
values: ['web-devlopment', 'recent', 'featured'] //HELP TO SEND MESSAGES OF ERROR
},
img_url: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: process.env.DEFAULT_IMAGE || 'default.svg'
},
created_at: {
type: DataTypes.DATE,
defaultValue: DataTypes.NOW,
allowNull: false
},
updated_at: {
type: DataTypes.DATE,
defaultValue: DataTypes.NOW
}
},{
timestamps: false
})
export default Posts
I believe the issue is with the hasMany definition. Because there can be many post IDs per user, you want to define the relationship but would not want a posteds column in the users table.
instead of:
Users.hasMany(Posts, {foreignKey: 'posteds'})
have you tried this?
Users.hasMany(Posts, { as: 'posts'})
I referenced this tutorial link, maybe it will be helpful:
https://bezkoder.com/sequelize-associate-one-to-many/

Sails JS : Can we use different field than primary key as foreign key?

I am using MongoDB and SailsJS for developing a web-app.
Here are the models.
USER MODEL
module.exports = {
tableName : 'users',
attributes: {
firstname: { type: 'string', required: true, columnType: 'varchar(55)' },
lastname: { type: 'string', required: true, columnType: 'varchar(55)' },
email: { type: 'string', required: true, columnType: 'varchar(65)', unique: true },
status: { type: 'number', columnType: 'tinyint(1)', defaultsTo: 1 },
createdAt: { type: 'number', autoCreatedAt: true, },
updatedAt: { type: 'number', autoUpdatedAt: true, },
user_role: { collection: 'userRole', via: 'user' },
},
};
USER ROLE MODEL
module.exports = {
tableName : 'user_roles',
attributes: {
role_title: { type: 'string', required: true, columnType: 'varchar(35)' },
role_name: { type: 'string', required: true, columnType: 'varchar(35)', unique: true },
role_code: { type: 'number', required: true, columnType: 'smallint(4)', unique: true },
status: { type: 'number', columnType: 'tinyint(1)', defaultsTo: 1 },
createdAt: { type: 'ref', autoCreatedAt: true, columnType: 'datetime', },
updatedAt: { type: 'ref', autoUpdatedAt: true, columnType: 'datetime', },
user: { collection: 'user', via: 'user_role' },
},
};
I want to use user_role.role_code as foreign_key. Can we achieve this in Sails JS?

Resources