graphql-tools
graphql-tools copied to clipboard
batchDelegateToSchema creates a duplicate of data from response for every resulting fields
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

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 :)