p3ac3
p3ac3

Reputation: 161

Fetching data with One to Many/Many to One and Many to Many in TypeORM using javascript

Hi i'am having a problem fetching my data with a profile, kids and toys, which the profile is the parent of the kids and kids is the parent of the toys. I already created fetching the data with "one to many" and "many to one" of profile and kids. Now i want the toys be in the kids attribute.

Here's my table looks like.. enter image description here

Here's my entities..

ProfileEntity.js

var {EntitySchema} = require("typeorm")

module.exports = new EntitySchema({
    name "Profile",
    tableName: "profile",
    columns: {
        profile_id: {
            primary: true,
            type: "integer"
        },
        name: {
            type: "varchar"
        },
        age: {
            type: "integer"
        }
    },
    relations: {
        kids: {
            target: "Kids",
            type: "one-to-many",
            inverseSide: "profile"
        }
    }
});

KidsEntity.js

var {EntitySchema} = require("typeorm")

module.exports = new EntitySchema({
    name "Kids",
    tableName: "kid",
    columns: {
        kid_id: {
            primary: true,
            type: "integer",
        },
        profile_id: {
            primary: true,
            type: "integer"
        },
        kid_name: {
            type: "varchar"
        },
        age: {
            type: "integer"
        }
    },
    relations: {
        profile: {
            target: "Profile",
            type: "many-to-one",
            joinColumn: {
                name: "profile_id"
            }
        }
    }
});

now when i call the

const data = await connection.getRepository("Profile").find({
    where: {
        name: "Doe"
    },
    relations: {
        kids: true
    }
});

it gives me an array like this which is correct

[
    {
        "profile_id": 1,
        "name": "Doe",
        "age": 28,
        "kids": [
            {
                "kid_id": 1,
                "profile_id": 1,
                "kid_name": "Coco",
                "age": 2
            },
            {
                "kid_id": 2,
                "profile_id": 1,
                "kid_name": "Melon",
                "age": 3
            }
        ]
    }
]

Now i want the Toys data be inside the kids attribute like this.

[
    {
        "profile_id": 1,
        "name": "Doe",
        "age": 28,
        "kids": [
            {
                "kid_id": 1,
                "profile_id": 1,
                "kid_name": "Coco",
                "age": 2
                "toys": [
                    {
                        "toy_id": 1,
                        "kid_id": 1,
                        "toy_name": "Golf Set",
                        "for": "2-3"
                    },
                    {
                        "toy_id": 2,
                        "kid_id": 1,
                        "toy_name": "Trucks",
                        "for": "2-3"
                    },
                ]
            },
            {
                "kid_id": 2,
                "profile_id": 1,
                "kid_name": "Melon",
                "age": 3,
                "toys": [
                    {
                        "toy_id": 3,
                        "kid_id": 2,
                        "toy_name": "Barbie",
                        "for": "3-5"
                    }
                ]
            }
        ]
    }
]

How can i fetch the data like this? thanks in advance.

Upvotes: 0

Views: 450

Answers (1)

Nikolay
Nikolay

Reputation: 12245

It appears that according to your data structure, it is nested relations you are after, not "many-to-many" relations. If you actually wanted many-to-many, then you could have defined a separate "toys" table and then something like "kids_toys" table that establishes a connection between "kids" and "toys".

But for now, following your current setup. First, you can define relations for "toys" like you did for "kids":

module.exports = new EntitySchema({
    name "Kids",
    ...
    relations: {
        profile: {
          ...
        },
        toys: {
            target: "Toys",
            type: "one-to-many",
            inverseSide: "kid"
        }
    }

Then add definition for the Toys table itself (add other fields properly to Toys.js):

module.exports = new EntitySchema({
    name "Toys",
    columns: {
        toy_id: {
            primary: true,
            type: "integer",
        },
        kid_id: {
            type: "integer"
        },
      ...
    }
    ...
    relations: {
        kid: {
            target: "Kids",
            type: "many-to-one",
            joinColumn: {
                name: "kid_id"
            }
        }
    }

And finally do the nested query:

    const data = await manager.getRepository("Profile").find({
        where: {
            name: "Doe"
        },
        relations: {
            kids: {
                toys: true
            }
        }
    });

Please note that typeorm targets typescript primarily, it's so much easier to work with it in typescript (much less to write). Not sure, why you are defining your entities using plain javascript with typeorm?

Upvotes: 2

Related Questions