Search code examples
graphqlrelayjsrelay

Relay/GraphQL add custom field to connection


I am trying to add the totalcount of records to be used for pagination. Right now i can see the connection i am having trouble modifying it to get my totalCount to be apart of it.

    Books: {
        type: BooksConnection.connectionType,
        args: { ...connectionArgs, isbn: { type: GraphQLString }, publisher: {type: GraphQLString}},
        resolve: ( obj, { ...args }, context, { rootValue: objectManager } ) =>
        {
            let user = obj;
            let FormatedArgs = MasterFields.FormatPredicate(args);
            return objectManager.getListBy( 'Book', user, FormatedArgs.queryArgs, objectManager.getViewerUserId( ) ).then( ( arr ) =>
            {

                let result = {};
                result.Books = arr;
                result.totalCount = arr.length;
;
                //Originally i would just pass arr instead of result.
                return connectionFromArray( result, FormatedArgs.connArgs);
            } )
        }
    },

When i get the connection object in the BookConnection in this case. I want to be able to assign that value to a field.

export default connectionDefinitions( {
    name: 'Books',
    nodeType: BookType,
    connectionFields: () => ({
        totalCount: {
            type: GraphQLInt,
            resolve: (connection) => { console.log(connection); return connection.totalCount; },
            description: `A count of the total number of objects in this connection, ignoring pagination.
This allows a client to fetch the first five objects by passing "5" as the
argument to "first", then fetch the total count so it could display "5 of 83",
for example.`
        }
})
});

How can I make totalCount a property of the connection variable?

I found part of the answer here: How to pass total count to the client in pageInfo


Solution

  • This was very obvious after starring at this for a hour or so . I couldn't figure out how to receive the totalCount value from connectionFromArray() This is how i overwrote it.

        Books: {
            type: BooksConnection.connectionType,
            args: { ...connectionArgs, isbn: { type: GraphQLString }, publisher: {type: GraphQLString}},
            resolve: ( obj, { ...args }, context, { rootValue: objectManager } ) =>
            {
                let user = obj;
                let FormatedArgs = MasterFields.FormatPredicate(args);
                return objectManager.getListBy( 'Book', user, FormatedArgs.queryArgs, objectManager.getViewerUserId( ) ).then( ( arr ) =>
                {
    
                    let result  = connectionFromArray( arr, FormatedArgs.connArgs);
    ;
                    result.pageInfo.totalCount = arr.length;
    
    
                    return result;
                } )
            }
        },
    

    Now this is me complaining.

    function connectionFromArray(data, args) {
      return connectionFromArraySlice(data, args, {
        sliceStart: 0,
        arrayLength: data.length
      });
    }
    function connectionFromArraySlice(arraySlice, args, meta) {
      var after = args.after;
      var before = args.before;
      var first = args.first;
      var last = args.last;
      var sliceStart = meta.sliceStart;
      var arrayLength = meta.arrayLength;
    
      var sliceEnd = sliceStart + arraySlice.length;
      var beforeOffset = getOffsetWithDefault(before, arrayLength);
      var afterOffset = getOffsetWithDefault(after, -1);
    
      var startOffset = Math.max(sliceStart - 1, afterOffset, -1) + 1;
      var endOffset = Math.min(sliceEnd, beforeOffset, arrayLength);
      if (typeof first === 'number') {
        endOffset = Math.min(endOffset, startOffset + first);
      }
      if (typeof last === 'number') {
        startOffset = Math.max(startOffset, endOffset - last);
      }
    
      // If supplied slice is too large, trim it down before mapping over it.
      var slice = arraySlice.slice(Math.max(startOffset - sliceStart, 0), arraySlice.length - (sliceEnd - endOffset));
    
      var edges = slice.map(function (value, index) {
        return {
          cursor: offsetToCursor(startOffset + index),
          node: value
        };
      });
    

    Above is the graphql-relay lib that has this function. What is the purpose of not passing us arrayLength when they obviously have it to perform there paging?