I'm struggling with a good title for this issue, so apologies. For that.
What I'm trying to achieve;
I have 3 Entities in use for this dataloader
UserClubPlayer
- Each
Usercan create aClubUserhas aOneToManyRelationship withClub- When a
Usercreates aClubtheUseridfield is set as the value of thecreatorIdfield inClub
- The
Userthat is the creator of eachClubcan create aPlayerto assign to theClubClubhas aOneToManyRelationship withPlayer- When a
Usercreates aPlayerat a club theClubidfield is set as the value of theuserIdfield inPlayer - A
Userwho is a creator of aClubcan link aPlayerto aUser, theidfield is set as the value of theuserIdfield inPlayer
So essentially a single User can be both a creator of a Club and a Player of a Club, so can be linked to a Club by either being a creator of a player of the club.
The issue
I want a FieldResolver field called allClubs to return all Clubs in which the User is either the creator or the player of a club.
This is what I currently have
@FieldResolver(() => [Club])
@Loader<number, Club[]>(
async (
userIds,
{
context: {
req: {
session: { userId },
},
},
}: { context: MyContext },
) => {
// get all clubs where user is either creator or a player
const clubs = await getConnection()
.getRepository(Club)
.createQueryBuilder('c')
.distinct()
.leftJoinAndMapMany('c.players', Player, 'p', 'c."id" = p."clubId"')
.where('c."creatorId" In (:...userIds)', { userIds })
.orWhere('p."userId" = :userId', { userId })
.getMany();
// group all clubs by creatorId
const clubsById = groupBy(clubs, 'creatorId');
return userIds.map((id) => clubsById[id] ?? []);
},
)
allClubs(@Root() root: User): (dataloader: DataLoader<number, Club[]>) => Promise<Club[]> {
return (dataloader: DataLoader<number, Club[]>) => dataloader.load(root.id);
}
So, I need the field to return an array of Club
I currently have the key of the DataLoader as the User id
Inside the Loader I have a query that returns all of the clubs where the user is either the creator or the player of the club. With the following structure returned
Club {
id: 5,
name: 'Club Name',
creatorId: 10,
players: [
Player {
id: 2,
name: 'Player name',
clubId: 5,
},
Player {
id: 7,
name: 'Player name 2',
clubId: 5,
}
]
}
I'm not sure how to group it correctly so that when I loop over all of the provided user ids from the key that I can retrieve where the user is a player.
Currently, it's only where the user is the creator
Let's say for the above example the User id is 7, they are not the creator of the Club, but they are a Player, how would I ensure that, that Club gets returned in the Loader and not just those Clubs where they are creator?
Any ideas how I can maybe restructure the query in some way to achieve this, or any other methods to achieve the same would be very much appreciated.