4

I'm new in typeGraphQL and my question about possible to to count result list elements

I have model type Books

import { Field, ID, ObjectType, Root } from "type-graphql";
import { Model, Column } from "sequelize-typescript";


@ObjectType()
export default class Books extends Model<Books> 
{

    @Field(() => ID)
    @Column
    id: number;

    @Field(() => String)
    @Column
    bookName: string;

}

Query in Resolver

@Query(() => [Books])
async getBooks()
{
    return Books.findAll()
}

when run query in graphiQL

getTest
{
    id
    bookName
}

get response

"getBooks" : 
[
    {
        "id": "1",
        "bookName": "bookOne"
    },
    {
        "id": "2",
        "bookName": "bookTwo"
    }
]

But i need to add aditional field, for example get the totalCount of all received items. How to do it properly? Now we have to create a separate query, but for large samples it is quite inconvenient and leads to duplication of complex and large queries

@Query(() => [Books])
async countBooks()
{
    return Books.findAll().length
}

I've tried creating a separate union type for the number of elements and the model itself

@ObjectType()
export default class UnionType extends Model<UnionType> 
{

    @Field(() => [Books])
    books: Books[];

    @Field(() => Int)
    totalCount(@Root() parent : UnionType) : number 
    {
        return parent.books.length;
    }

}

and run next query in resolver

@Query(() => [UnionType])
async getBooksAndCountAll()
{
    let union : any = {}        

    union.books = Books.findAll();
    union.totalCount = union.books.length;

    return union;
}

But have error in graphiQL when run query error "message": "Expected Iterable, but did not find one for field Query.getBooks.", as I understand it is not transmitted the data that the model expects

I trying to use createUnionType

import { createUnionType } from "type-graphql";
const SearchResultUnion = createUnionType({
    name: "Books", // the name of the GraphQL union
    types: [Books, CountType], // array of object types classes
  });

where UnionType

@ObjectType()
export default class CountType extends Model<CountType> 
{
    @Field(() => Int, { nullable : true })
    totalCount: number;
}

Query in Resolver

    @Query(returns => [SearchResultUnion])
    async getBooks(
    ): Promise<Array<typeof SearchResultUnion>>{

        return new Promise((resolve, reject) => {
            Books.findAll()
            .then(books => {

                let totalCount = books.length;

                return [...books, ...totalCount];
            });
        });
    }

But have the error in string return [...books, ...totalCount]; на ...totalCount Type 'number' must have a '[Symbol.iterator]()' method that returns an iterator.

If you do not pass ...totalCount the request works, but there is no respectively already there is no totalCount

getTest{
__typename
  ... on Books
  {
    id
    bookName
  }
}

request

 "getBooks": [
    {
        "id": "1",
        "bookName": "bookOne"
    },
    {
        "id": "2",
        "bookName": "bookTwo"
    }
  ]

So, as a result I need a request

getTest
{
    totalCount
    __typename
      ... on Books{
        id
        bookName
      }
}

Is it possible?

1 Answer 1

1

the answer from https://github.com/19majkel94/
Thanks, Michał Lytek

@ObjectType()
export default class GetBooksResponse {
    @Field(() => [Books])
    books: Books[];

    @Field(() => Int)
    totalCount : number;
}

@Query(() => GetBooksResponse)
async getBooks() {
  const books = await Books.findAll();
  return { books, totalCount: books.length };
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.