Dictionary in GraphQL resolver of NestJS

Dictionary in GraphQL resolver of NestJS


1

In my NestJS project I’m creating a GraphQL endpoint for a service that returns a dictonary object:

{
 [key: number]: MyDataDto
}

In my .interfaces.ts file I would like to have something like:

interface ArrayAsObject<T> {
  [key: number]: T
}

@ObjectType()
export class MyDataDtoAsDictionary implements ArrayAsObject<MyDataDto> {
  @Field(() => MyDataDto)
  [key: number]: MyDataDto
}

But it gives me an error on the line with @Field

Decorators are not valid here. (ts1206)

If I remove the @Field decorator it throws:

Type MyDataDtoAsDictionary must define one or more fields.

What is the right way to decorate that kind of object for GraphQL resolver?

3

  • Did you ever find the answer or did you choose another approach?

    – TheHiggsBroson

    Oct 19, 2020 at 23:41

  • 1

    @TheHiggsBroson No, I haven't find any proper solution, so I had to create another service that would return an array of MyDataDto and handle it a bit differently in frontend app.

    – Sergei Klinov

    Oct 20, 2020 at 4:04

  • Has anyone had the solution, graphql seems not to encourage it: stackoverflow.com/a/41559109/4984888

    – Neo.Mxn0

    Dec 15, 2021 at 9:48


1 Answer
1


0

You can use graphql-type-json as response type of a Query in your Resolver.

First of all, you need to install graphql-type-json: https://www.npmjs.com/package/graphql-type-json

npm i graphql-type-json

With this, you can return a Dictionary with a Query like this:

export class EquipmentResolver { 
  private data: { [key: number]: MyDataDto } = {};

  @Query(() => graphqlTypeJson)
  async queryData() {
    return this.data;
  }
}

In a frontend project you can pipe this very easily with RxJS back to a Dictionary:

export class DataComponent {
  private data: { [key: number]: MyDataDto } = {};

  private loadData() {
    this.graphqlService
    .queryData()
    .pipe(
      map((response: { [key: number]: MyDataDto) => {
        this.data = response;
      })
    )
    .subscribe();
  }
}



Leave a Reply

Your email address will not be published. Required fields are marked *