Add custom select and map to property of entity

See original GitHub issue

Issue type:

[ ] question [ ] bug report [X ] feature request [ ] documentation issue

Database system/driver:

[X] cordova [X] mongodb [X] mssql [X] mysql / mariadb [X] oracle [X] postgres [X] sqlite [X] sqljs [X] websql

TypeORM version:

[ ] latest [ ] @next [ ] 0.x.x (or put your version here)

Steps to reproduce or a small repository showing the problem: What I to accomplish is to add a custom select that maps to a property of my Entity. I’ve found an work around but would like to know if there is an easier/cleaner way to do this.

So I’ve my model:

@Entity('groups')
export class Group extends BaseEntity{

    @PrimaryGeneratedColumn()
    id: number;

    @ManyToMany(type => User, user => user.groups)
    @JoinTable({
        name: 'groups_users',
        joinColumn: {
            name: 'group_id',
            referencedColumnName: 'id'
        },
        inverseJoinColumn:
            {name: 'user_id',
                referencedColumnName: 'id'
            }
    })
    users: User[];

    active: boolean;
}

This entity has a ManyToMany relationship to User. The JoinTable groups_users has one extra column active this active indicates if the group that the user is linked to is visible.

When I query the groups to get all the groups for one user (also the inactive groups) I do this:

let query = this.groupRepository
            .createQueryBuilder('group')
            .innerJoin('groups_users', 'gu')
            .innerJoin('group.users', 'user', 'user.deleted_at is null AND group_user.user_id = :id',
                {id: userId})
            .orderBy('group.id', 'ASC')
            .andWhere('group.deleted_at IS NULL');

As you can see the Group entity has a property called active. As for now the active property is not seen by typeorm so what I did was the following:

I added this to the active property:

 @Column('tinyint', {
        nullable: true,
        select: false
    })
    active: boolean;

By setting select to false the other queries won’t break (since active isn’t a real column inside the group table).

Now I added this to the query:

.addSelect(s => s.select('active').from('groups_users', 'gu').where('gu.group_id = group.id AND gu.user_id = :id', {id: userId}), 'group_active')

By doing this the active property is filled for each user and the active is true or false according the 0 or 1 in JoinTable.

To query I ended up with is:

let query = this.groupRepository
            .createQueryBuilder('group')
            .addSelect(s => s.select('active').from('groups_users', 'gu').where('gu.group_id = group.id AND gu.user_id = :id', {id: userId}), 'group_active')
            .innerJoin('groups_users', 'gu')
            .innerJoin('group.users', 'user', 'user.deleted_at is null AND group_user.user_id = :id',
                {id: userId})
            .orderBy('group.id', 'ASC')
            .andWhere('group.deleted_at IS NULL');

which leaves me with the correct output. Now this seems a little bit of a hack or is this the propper way to do this?

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:7
  • Comments:36 (3 by maintainers)

github_iconTop GitHub Comments

73reactions
noorsheikhcommented, Jan 13, 2020

Hello Guys,

If someone still looking for an answer. Here is a workaround that I did for myself. My Case: I had a Job entity and a Category entity. I wanted to list all categories with total # of jobs posted for each category something like this:

[
    {
        "id": 2,
        "name": "Accounting",
        "total": "1"
    },
    ...
]

Here is my DDL for job_categories table:

DROP TABLE IF EXISTS `job_category`;
CREATE TABLE `job_category` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `name` VARCHAR(20) NOT NULL
);

I do not have the total column stored in my category table. For a workaround I added a total column in my entity with { select: false } as below:

@Column('int', { select: false })
 total: number;

In my query builder I added an addSelect() with first parameter as COUNT(jobs.id) and second parameter for an alias as category_total. Note: As you can see I have prepend category_ to the alias total, this will map the total column to the actual result of category entity. Without category_ in the alias the total column will not be visible. My QueryBuilder:

return (await this.getRepository(JobCategory))
      .createQueryBuilder('category')
      .addSelect('COUNT(jobs.id)', 'category_total')
      .leftJoin('category.jobs', 'jobs')
      .groupBy('category.id')
      .orderBy('category.name', 'ASC')
      .getMany();
  }

Here is a debugging result: BEFORE the workaround:

(34) RowDataPacket {
node_1   |   category_id: 1,
node_1   |   category_name: 'IT/Engineering',
node_1   |   category_description: null,
node_1   |   category_icon: 'dice-d20',
node_1   |   total: '1'
node_1   | }

AFTER the workaround:

(35) RowDataPacket {
node_1   |   category_id: 2,
node_1   |   category_name: 'Accounting',
node_1   |   category_description: null,
node_1   |   category_icon: 'chart-line',
node_1   |   category_total: '1'
node_1   | }
32reactions
derSoerrn95commented, Sep 17, 2018

I also need this feature. Do u know when the 0.3.0 launch is?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Computed column with alias is not mapping into TypeORM ...
Issue 296 Select additional computed columns (still open); Issue 1822 Add custom select and map to property of entity (closed as duplicate) ...
Read more >
Select using Query Builder - typeorm - GitBook
Joining and mapping functionality. Add profilePhoto to User entity and you can map any data into that property using QueryBuilder : export class...
Read more >
Fluent API - Configuring and Mapping Properties and Types
Entity splitting uses multiple calls to the Map method to map a subset of properties to a specific table.
Read more >
Advanced field value conversion using custom mapping types
We create a simple entity with a field $point which holds a value object Point representing the latitude and longitude of the position....
Read more >
Change custom properties in SolarWinds Platform
To add the same value for multiple objects, select the objects, and click Edit Value(s). Select the property, enter the value, and click...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found