Skip to content

batchDelegateToSchema creates a duplicate of data from response for every resulting fields #4958

Open
@Jakub41

Description

@Jakub41

Hello,

I've been implementing in an API the method batchDelegateToSchema from the library.

I'm sharing the following media to show the issue I have with the response and details immediately below

CleanShot 2023-01-10 at 12 00 21

As you see from that query I'm calling I'm receiving a result and what is wrong I'm getting the data duplicated for the fields which should be empty objects.

In my example, I'm retrieving data for one candidate and I want to know the events that the candidate has signed.
As per DB the candidate has only APPOINTMENT_PHONE as event so I'm expecting this resulting object from the query

{
  "data": {
    "candidate": {
      "id": "CY-001745",
      "callReminders": {
        "nodes": [
          {
            "id": "33116",
            "startTime": "2023-01-10T08:57:00.000Z",
            "type": "APPOINTMENT_PHONE"
          }
        ],
        "totalCount": 1
      },
      "siteAppointments": {
        "nodes": [
        ],
        "totalCount": 0
      }
    }
  }
}

Instead, I see the same result replicated in the siteAppointments which is wrong.

As ref of wrong response

{
  "data": {
    "candidate": {
      "id": "CY-001745",
      "callReminders": {
        "nodes": [
          {
            "id": "33116",
            "startTime": "2023-01-10T08:57:00.000Z",
            "type": "APPOINTMENT_PHONE"
          }
        ],
        "totalCount": 1
      },
      "siteAppointments": {    -- THIS HEAR HAS TO BE EMPTY [] --
        "nodes": [
          {
            "id": "33116",
            "startTime": "2023-01-10T08:57:00.000Z",
            "type": "APPOINTMENT_PHONE"
          }
        ],
        "totalCount": 1
      }
    }
  }
}

I spent already hours understanding the issue and I'm sharing what I debugged

This is the resolver

events: {
      selectionSet: '{ id }',
      resolve(candidate, args, context, info) {
        return batchDelegateToSchema({
          schema: event,
          operation: 'query',
          fieldName: 'eventsByOwner',
          key: candidate.id,
          transforms: [transformEventsByOwner],
          argsFromKeys: keys => ({
            ...args,
            filter: {
              ...(args?.filter ?? {}),
              ownerTypes: ['CANDIDATE'],
              ownerIds: keys,
            },
          }),
          valuesFromResults: (results, keys) => {
            const allEvents = keys
              .map(findByOwnerId(results))
              .map(mapToConnection);
            console.log('allEvents: ', JSON.stringify(allEvents, null, 2));
            
            return allEvents;
          },

          context,
          info,
        });
      },
    },

On the console.log('allEvents: ', JSON.stringify(allEvents, null, 2));I see the result I need the correct one

allEvents:  [
  {
    "totalCount": 1,
    "nodes": [
      {
        "id": "33116",
        "startTime": "2023-01-10T08:57:00.000Z",
        "type": "APPOINTMENT_PHONE",
        "__typename": "Event"
      }
    ]
  }
]

But for some reason after that the result is duplicated inside the other field siteAppointments

I have no clue what's wrong here and I would like to find out a solution to that as it is blocking my release :(

As a detail the other methods used here

/**
 * Find an item in list of results by owner id.
 *
 * @param {Object[]} results - List of results.
 * @param {string} results[].ownerId - The item's owner id.
 * @returns {Object|undefined} - The item with matching owner id or undefined when item not found.
 */
export function findByOwnerId(results) {
  return id => results?.find(item => item?.ownerId === id);
}

/**
 * Map a result to a generic connection interface.
 *
 * @param {Object} result - A result (potentially empty or undefined).
 * @param {?number} result.totalCount - Total count of entities.
 * @param {?Object[]} result.nodes - Array of items.
 * @returns {{totalCount: number, nodes: Object[]}} - A connection with nodes and totalCount.
 */
export function mapToConnection(result) {
  return {
    totalCount: result?.totalCount ?? 0,
    nodes: result?.nodes ?? [],
  };
}

export const transformEventsByOwner = new WrapQuery(
  ['eventsByOwner'],
  extendedSelection('ownerId'),
  identity,
);

I hope you can help me with this issue

Thanks :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions