Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to delete nested entities in TypeORM and Nest.js

Tags:

typeorm

nestjs

I have one-to-many relation:

class User {
    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    name: string;

    @OneToMany(() => Phone, phone => phone.user, {cascade: true})
    phones?: Phone[];
}

Assume current data in database is following: user has two phone numbers:

{
  "id": 1,
  "name": "Jhon",
  "phones": [
    {"id": 1, "phone":  "123456"},
    {"id": 2, "phone":  "567809"}
  ]
}

I build UI (web-interface) and from web-interface I want to have possibility to delete a phone number from user profile. So I do it and following POST request comes from UI: second phone number deleted

{
  "id": 1,
  "name": "Jhon",
  "phones": [
    {"id": 1, "phone":  "123456"}
  ]
}

How to delete phone number id=2 from database? I use Nest CRUD module, as I understand from source code it just merges a new data from request with current data from database, so merging two phone numbers from database with the only phone number from request gives us array of tho phone numbers again and nothing deleted :frowning: I tried to do it manually and there are a lot of code!

  @Override()
  async updateOne(
    @ParsedRequest() req: CrudRequest,
    @ParsedBody() dto: UpdateUserDto,
    @Param('id') id: number,
  ): Promise<Shipment> {

    // use standart Nest.js way to save new user data into database
    await this.service.updateOne(req, dto);

    // load fresh user data from database
    const user = await this.service.findOne(id);

    const phonesFromUi = dto.phones;
    const phonesToBeDeleted = [];
    // loop phone numbers from database - detect which to be deleted
    user.phones.forEach((phoneFromDb) => {
      const hasThisPhoneOnUi = phonesFromUi.find((phoneFromUi) => phoneFromUi.id === phoneFromDb.id);
      if (!hasThisPhoneOnUi) {
        // looks like this phone number was deleted on ui, so delete it from database too
        phonesToBeDeleted.push(phoneFromDb);
      }
    });
    // actually delete phone numbers from database
    await this.connection.getRepositoryFor(Phone).remove(phonesToBeDeleted);

    // reload fresh user data from database to get fresh list of phone numbers after delition some of them
    const user = await this.service.findOne(id);

    return user;
  }

Is there any way to do it via TypeORM build in functions or methods? How to delete some elements from nested array?

like image 861
Petr Avatar asked Oct 18 '25 17:10

Petr


1 Answers

There is no very good support in typeorm for doing a join update, what I advise you to do is receiving the phones parameter and get a select of the phones that are related to the UserId and then delete the ids that are not in the new array:

const phones = await this.phoneRepository.find({userId:1});
const toDeletePhones = phones.filter((element)) => {
  return updatePhones.indexOf(element) === -1;
}
this.phoneRepository.remove(toDeletePhones);

then procede to update the user or yo can even do it before this

like image 175
RalphJS Avatar answered Oct 21 '25 09:10

RalphJS



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!