How to create two or more Resolve Field in Resolve Decorator in Nestjs?

3.1k views Asked by At

I am creating one nestjs graphql api. I write all function correctly. But when I need to add @ResolveField into @Resolver Decorator, I get into one problem. Can any tell me when I need two @ResolveField in one @Resolver, then How can I add it?

Here is Category Entity-(category.entity.ts)

@ObjectType()
export class Category {
    @Field(() => ID, { nullable: false })
    id: ObjectId;
    @Field(() => String, { nullable: false })
    name: string;
    @Field(() => String, { nullable: true })
    description: string;
    @Field(() => [Subcategory], { nullable: true })
    subCategory: Subcategory[];
    @Field(() => Date, { nullable: false })
    createdAt: DateScalar;
    @Field(() => Date, { nullable: false })
    updatedAt: DateScalar;
}

And Here is Subcategory Entity (sub-category.entity.ts)-

@ObjectType()
export class Subcategory {
    @Field(() => ID, { nullable: false })
    id: ObjectId;
    @Field(() => String, { nullable: false })
    name: string;
    @Field(() => Category, { nullable: false })
    category: Category;
    @Field(() => Date, { nullable: false })
    createdAt: DateScalar;
    @Field(() => Date, { nullable: false })
    updatedAt: DateScalar;
}

And This is Resolver (category.resolver.ts)-

@Resolver()
export class CategoryResolver {
    //Constructor
    constructor(private readonly categoryService: CategoryService) { }
    
    //Get All Category
    @Query(() => [Category], { name: "getCategories" })
    categories() {
        return this.categoryService.categories()
    }

    @ResolveField("subCategory", () => [Subcategory])
    subCategoryBatch(
        @Parent() category: Category
    ) {
        console.log(category)
    }



    //Get All Sub Category
    @Query(() => [Subcategory], { name: "getSubCategories" })
    subCategories() {
        return this.categoryService.subCategories();
    }
    @ResolveField("category", () => Category)
    categoryBatch(
        @Parent() subCategory: Subcategory
    ) {
        console.log(subCategory)
    }
}

Here you can see two @ResolveField Decorator. For working This I need to add Entity in @Resolver decorator, like-

@Resolver(Category)

or

@Resolver(Subcategory)

When I give Category then One ResolveField work perfectly, other is not working. Again When I give Subcategory then the other is working perfectly, but first one is not working. But When I give together then it gives me error-

@Resolver(Category, Subcategory)

Please help me. I need it Please help me. I can't solve it for 3 days. I search for the same things over internet but not finding any solutions.

1

There are 1 answers

5
o.c On

First i highly recomand you to organize your resolver like :

// ====== Queries =======

// ====== Mutations =======

// ====== Resolvers =======

Because resolveing field is available for all queries, when your api will grow you 'll need more readable file.

In the model, your Category field or subCat are currently not Category type, it's probably a ID ref to resolve. After resolving, your field become a Category. True question is, in your db, what's the type of your field ?

So try something like this :

  // ex for subCategory.entity.ts
  @Prop({ type: String, ref: 'Category' }) // Mongo
  @Field(() => Category) // GraphQL 
  parent: string; // TS

Then, to resolve this ref, you have to init a @ResolveField and use the correct service to resolve it, like :


  @ResolveField('parent', () => Category) // resolve 'parent' field to return Category type.
  async resolveParentCategory(@Parent() sub: SubCategory) // take parent object, here subCatefory, where the field to resolve exist. 
  {
      // resolve string ID ref, with correct db service to return parent Category.
      return this.service.getOneCat(sub.parent); 
  }

In this case, ResolveField resolve 'parent' to return Category type. The function take the @Parent object where the field "parent" to resolve is accessible,an id is expected here. A db service getOneCat resolve this id to return the complete Category object. It will work for all field 'parent' in this resolver now.

I hope i helped you, let me know if you need more explanation.

Edit - To resolve subCategory in Category result:

My example above should resolve your subfield category in SubCategory, just replace parent by category.

To resolve subCategories in Category it's the same way. But, you should have a subCategory: string[]; for TS in your Category model entity.

Then, in your resolver, resolve subCategory field, to return () => [SubCategory]. Parent become @Parent() cat: Category and resolve it with a service wich can take ids : string[] in arg and return all documents asked from your db. Like return this.service.getSubCatByIds(cat.subCategory).