What is the process of creating a typeorm relationship between orders and products?

My Orders Entity file in TypeOrm looks like this:

@Entity('orders')
export class OrdersEntity {
  @PrimaryGeneratedColumn('uuid') id: string;

  @CreateDateColumn() created: Date;

  @UpdateDateColumn() updated: Date;

  @Column('text', { default: StatusEnum.PROCESSING }) status: string;

  // relationships

  @ManyToOne(type => UsersEntity, customer => customer.orders)
  customer: UsersEntity;

  @OneToMany(type => ProductsEntity, products => products.order, {cascade: true})
  products: ProductsEntity[];
}

This is the structure of my Products Entity:

export class ProductsEntity {
  @PrimaryGeneratedColumn('uuid') id: string;

  @CreateDateColumn() created: Date;

  @UpdateDateColumn() updated: Date;

  @Column({ type: 'text', unique: true }) name: string;

  @Column('text') description: string;

  @Column('integer') unitsOnStock: number;

  @Column('numeric', { precision: 10, scale: 2 }) price: number;

  // relationships

  @ManyToOne(type => CategoriesEntity, category => category.products)
  category: CategoriesEntity;

  @ManyToOne(type => OrdersEntity, order => order.products)
  order: OrdersEntity;
}

In the orders.service.ts file, there is a function used to create new orders:

  async create(data: OrdersDto, userId: string) {
    const { productsArray } = data;
    
    const products: ProductsEntity[] = [];
    for (const productItem of productsArray) {
      const product = await this.productsRepository.findOne({
        where: { id: productItem.productId },
      });
      if (!product) {
        throw new HttpException("Product's ID not found", HttpStatus.NOT_FOUND);
      }
      if (product.unitsOnStock - productItem.quantity < 0) {
        throw new HttpException('Insufficient stock', HttpStatus.BAD_REQUEST);
      } else {
        products.push({ ...product });
      }
    }
    const user = await this.usersRepository.findOne({ where: { id: userId } });

    for (const productItem of productsArray) {
      const product = await this.productsRepository.findOne({
        where: { id: productItem.productId },
      });
      await this.productsRepository.update(product.id, {
        unitsOnStock: product.unitsOnStock - productItem.quantity,
      });
    }

    const order = await this.ordersRepository.create({
      products,
      customer: user,
    });

    await this.ordersRepository.save(order);
    return order;
  }

The goal is to have an additional column in the orders table that contains an array of objects {productId: string, quantity: string} for each order.

I attempted using @JoingTable but encountered issues...

If you have any suggestions or ideas, they would be greatly appreciated. Thank you in advance!

Answer №1

It's not efficient to handle it the way you explained. A better approach would be to create a separate table for the actual products included in an order. Here is a suggestion:

@Entity('order_items')
export class OrderItemEntity {
@PrimaryGeneratedColumn('uuid')
id: string;

@Column('uuid')
productId: string;

@Column()
quantity: number;

@ManyToOne(() => OrdersEntity, order => order.orderItems)
order: OrdersEntity;
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Customizing MUI DataGrid: Implementing unique event listeners like `rowDragStart` or `rowDragOver`

Looking to enhance MUI DataGrid's functionality by adding custom event listeners like rowDragStart or rowDragOver? Unfortunately, DataGrid doesn't have predefined props for these specific events. To learn more, check out the official documentati ...

What is the best way to ensure that the operations are not completed until they finish their work using RX

Is there a way to make RXJS wait until it finishes its work? Here is the function I am using: getLastOrderBeta() { return this.db.list(`Ring/${localStorage.getItem('localstorage')}`, { query: { equalTo: fa ...

Moving information from two modules to the service (Angular 2)

Recently in my Angular2 project, I created two components (users.component and tasks.component) that need to pass data to a service for processing before sending it to the parent component. Code snippet from users.component.ts: Import { Component } fro ...

When accessing from the frontend (Angular), the User.FindFirst(ClaimTypes.NameIdentifier) method does not return any values

I'm encountering a new issue - just as the title suggests. I've managed to identify where the problem occurs but I'm unable to resolve it. Let's start from the beginning. In the backend (ASP.NET 3.0), I have a class AuthController with ...

Attempting to invoke setState on a Component before it has been mounted is not valid - tsx

I've searched through various threads regarding this issue, but none of them provided a solution that worked for me. Encountering the error: Can't call setState on a component that is not yet mounted. This is a no-op, but it might indicate a b ...

Angular's getter value triggers the ExpressionChangedAfterItHasBeenCheckedError

I'm encountering the ExpressionChangedAfterItHasBeenCheckedError due to my getter function, selectedRows, in my component. public get selectedRows() { if (this.gridApi) { return this.gridApi.getSelectedRows(); } else { return null; } } ...

What is the best way to link multiple select tags in an HTML document?

I am working with a data grid that contains student information such as Name, Class, and Score. Each row has a checkbox for selection. The requirement is that when the user selects one or more rows and clicks on the "show information" Button, a new windo ...

Arrange an array of objects by making a nested API call in Angular

My task involves sorting an array of objects based on the response from the first API call in ascending order. The initial API call returns a list of arrays which will be used for the subsequent API call. The first API call fetches something like this: [0 ...

Issue with Typescript typing for the onChange event

I defined my state as shown below: const [updatedStep, updateStepObj] = useState( panel === 'add' ? new Step() : { ...selectedStep } ); Additionally, I have elements like: <TextField ...

Managing state within SolidJS components using Immer's "produce" for nested state handling

I've been working on a SolidJS application where I store a large JSON object with nested objects. For undo and redo actions, I'm using Immer to generate patches. Although technically I'm storing a class with multiple layers of nesting, Immer ...

The JokesService (?) has encountered dependency resolution issues that Nest is unable to resolve

Currently delving into the world of NestJS and feeling a bit perplexed about the workings of "modules". In my project, I have two modules namely JokesModule and ChuckNorrisApiModule. My goal is to utilize the service provided by ChukNorrisService within th ...

Understanding how to infer literal types or strings in Typescript is essential for maximizing the

Currently, my goal is to retrieve an object based on the parameter being passed in. I came across a similar question that almost meets my requirements. TypeScript function return type based on input parameter However, I want to enhance the function's ...

Importing Angular libraries with the * symbol

One of the key modules in my library is sha256. To import it, I had to use the following syntax: import sha256 from 'sha256'; However, while researching this issue, I came across a question on Stack Overflow titled: Errors when using MomentJS ...

Typescript: Utilizing a generic array with varying arguments

Imagine a scenario where a function is called in the following manner: func([ {object: object1, key: someKeyOfObject1}, {object: object2, key: someKeyOfObject2} ]) This function works with an array. The requirement is to ensure that the key field co ...

Steps to filter types by a singular property assessment

export type HalfSpin = { halfspin: string } export type FullSpin = { fullspin: string } export type SpinType = | HalfSpin | FullSpin export function isHalfSpin(_: SpinType) ...

Encountering difficulty in reaching the /login endpoint with TypeScript in Express framework

I'm currently working on a demo project using TypeScript and Express, but I've hit a roadblock that I can't seem to figure out. For this project, I've been following a tutorial series from this blog. However, after completing two parts ...

Tips on utilizing a connected service in a custom Azure DevOps extension's index.ts file

I have created a unique extension for Azure DevOps that includes a specialized Connected Service and Build task. When setting up the task through the pipeline visual designer, I am able to utilize the Connected Service to choose a service and then populate ...

Seamless database migrations using sequelize and typescript

I've been exploring the concept of generating migration files for models that already exist. When I use the "force: true" mode, tables are automatically created in the database, so I find it hard to believe that creating migration files automatically ...

Is it possible to import a module that was exported in Node.js using the SystemJS import method?

When working on a Node project, we typically import modules using the require keyword. Is it possible to import the same module in an Angular 2 project using import {} from '', even if the d.ts file is not available? For instance, can I incorpora ...

"Exploring the TypeScript typing system with a focus on the typeof operator

My goal is to create a function that will return the typeof React Component, requiring it to adhere to a specific props interface. The function should return a type rather than an instance of that type. Consider the following: interface INameProps { ...