简体   繁体   中英

possible to count result list elements in type-graphql

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?

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 };
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM