#Issue with custom Bidirectional Hook and bulk edit

6 messages · Page 1 of 1 (latest)

plain mountain
#

Hi guys,

I have a hook that updates relationship field between collections.
I got it working when editing in a collection document edit page.

On Lesson A edit page, I set Course relationship to Course A. It does work as intended, and shows up on Course A page.
However, when bulk editing on lessons list view, only one lesson gets added to target course.

Same issue with skill collection.

btw, I know hook for bidirectional relationships are not recommended, but I don't manage to make join+relation field work when querying on the front, and I'm ok with this hook solution, if I get it to work that is.

Code below.

If someone could help me, that'd be much much appreciated.
Sorry for 6 messages below, I don't know how to share code otherwise.

barren kestrelBOT
plain mountain
#

src/hooks/bidirectionalRelation/addRelations.ts

import { Payload, CollectionConfig } from 'payload';

interface CollectionRelationConfig {
  collectionName: string;
  relationField: string;
}

/**
 * Établit une relation pour chaque ID sélectionné.
 */
export async function addRelations(
  newRelations: string[],
  idForAdd: string,
  currentCollection: CollectionRelationConfig,
  targetCollection: CollectionRelationConfig,
  payload: Payload
) {
  // POUR CHAQUE RELATION AJOUTER CHEZ LE DOC VISÉE

  for (let newRelationId of newRelations) {
    try {
      // doc lié de la relation souhaité
      const docOfRelation = await payload.findByID({
        collection: targetCollection.collectionName as 'courses' | 'lessons' | 'skills',
        id: newRelationId,
        depth: 0,
        draft: true,
      });

      // les relations qui composent déjà ce doc sur le champ correspondant
      const baseRelationsOfDoc = docOfRelation[currentCollection.relationField]
        ? docOfRelation[currentCollection.relationField]
        : [];

      const mergedBaseWithNewRelation = [...baseRelationsOfDoc, idForAdd];

      await payload.update({
        collection: targetCollection.collectionName as 'courses' | 'lessons' | 'skills',
        id: newRelationId,
        depth: 0,
        draft: false,
        data: {
          [currentCollection.relationField]: mergedBaseWithNewRelation,
        },
        context: {
          hookAlreadyRun: true,
        },
      });
    } catch (err) {
      console.error(err);
    }
  }
}
#

src/hooks/bidirectionalRelation/deleteRelations.ts

import { CollectionConfig, PayloadRequest } from 'payload';

interface CollectionRelationConfig {
  collectionName: string;
  relationField: string;
}

/**
 * Supprime une relation pour chaque ID sélectionné.
 */
export async function deleteRelations(
  removedRelations: string[],
  idForRemove: string,
  currentCollection: CollectionRelationConfig,
  targetCollection: CollectionRelationConfig,
  req: PayloadRequest,
) {
  // POUR CHAQUE RELATION SUPPRIMER CHEZ LE DOC VISÉE

  for (let removedRelationId of removedRelations) {
    try {
      // doc lié de la relation souhaité
      const docRelation = await req.payload.findByID({
        collection: targetCollection.collectionName as 'courses' | 'lessons' | 'skills',
        id: removedRelationId,
        depth: 0,
        draft: true,
      });

      // les relations qui composent déjà ce doc sur le champ correspondant
      const baseRelationsOfDoc = docRelation[currentCollection.relationField]
        ? docRelation[currentCollection.relationField]
        : [];

      // Filtrer pour enlever l'ID à supprimer
      const filteredRelations = baseRelationsOfDoc.filter((id: string) => id !== idForRemove);

      await req.payload.update({
        collection: targetCollection.collectionName as 'courses' | 'lessons' | 'skills',
        id: removedRelationId,
        depth: 0,
        draft: false,
        data: {
          [currentCollection.relationField]: filteredRelations,
        },
        context: {
          hookAlreadyRun: true,
        },
      });
    } catch (err) {
      console.error(err);
    }
  }
}