Closed dipeshba closed 11 months ago
Could you explain a bit more how your situation is and what you want? Also see custom endpoints on how to create a custom endpoint (I do see we did not mention mutations here but it's very similar), also a bit more info here
So basically, I have an Item entity and whenever an item is created, i want to create few other new related entities (also probably run a TypeOrm transaction). I thought of extending TypeOrmQueryService as mentioned here https://tripss.github.io/nestjs-query/docs/persistence/typeorm/custom-service . But createOne function doesn't seems to receive Item Input DTO and instead gets the Item entity itself, which means i can't pass any field that or not in Item entity, but in ItemInputDTO i have created.
Here is what i though of doing...
import { QueryService } from '@ptc-org/nestjs-query-core'
import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Item } from './entities/item.entity';
@QueryService(Item)
export class ItemService extends TypeOrmQueryService<Item> {
constructor(
@InjectRepository(Item) repo: Repository<Item>,
) {
super(repo);
}
createOne(record: Item): Promise<Item> {
// TO DO: Call item repository to save item
}
}
Okay so to double check, the TodoItemService is added as ServiceClass
to the module? You could then indeed overwrite the createOne
like this:
public async createOne(record: DeepPartial<Item>): Promise<Item> {
const createdRecord = await super.createOne(record)
// Do your stuff with it
return createdRecord
}
Only issue here is, record: DeepPartial<Item>
I would like to receive ItemInputDTO as there are some additional fields in it, that don't directly correspond to Item entity.
Are you than maybe looking for @BeforeCreateOne
?
Would like to point out that the interface maybe says you get DeepPartial<Item>
but you actually get CreateOneInputType<Item>
Probably do something like this:
Are you than maybe looking for
@BeforeCreateOne
?
I checked this as well. But this seems to be useful if i just want to modify something in DTO not create return it back? You think i can use it to create and save new item?
Would like to point out that the interface maybe says you get
DeepPartial<Item>
but you actually getCreateOneInputType<Item>
So you mean to say I can do?
createOne(input: CreateOneInputType<CreateItemInputDto> ): Promise<Item> {
// Do my stuff and return Item entity
}
That should be correct :)
That should do job then! Worth to add this in documentation. I will give this a try and update :) Really thanks for your help on this!
Not sure if this works properly. I get the IDE error. Attached screenshot and the code below:
import { QueryService } from '@ptc-org/nestjs-query-core'
import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Item } from './entities/item.entity';
import { CreateOneInputType } from '@ptc-org/nestjs-query-graphql';
import { CreateItemInputDto } from './dto/create-item-input.dto';
import _ from 'lodash';
import { Sku } from 'src/skus/entities/sku.entity';
@QueryService(Item)
export class ItemService extends TypeOrmQueryService<Item> {
constructor(
@InjectRepository(Item)
private itemRepository: Repository<Item>,
@InjectRepository(Sku)
private skuRepository: Repository<Sku>,
) {
super(itemRepository);
}
public async createOne(input: CreateOneInputType<CreateItemInputDto>): Promise<Item> {
const item = this.itemRepository.create({
name: input.input.name,
description: input.input.description,
measuringUnitId: input.input.measuringUnitId,
skus: [
this.skuRepository.create({
quantity: input.input.quantity,
skuId: input.input.skuId || _(input.input.name).kebabCase().toUpperCase(),
})
]
}
)
return this.itemRepository.save(item);
}
}
I think you need to update this:
public async createOne(input: CreateOneInputType<CreateItemInputDto>): Promise<Item> {
To
public async createOne(input: CreateItemInputDto): Promise<Item> {
Or
public async createOne(input: DeepPartial<Item>): Promise<Item> {
Closing, if still an issue please reopen.
Hey I think I'm having trouble with this.
I'm trying to add an additional field to the 'createOneX' input that is not stored with the entity:
import { Field, InputType } from '@nestjs/graphql';
import { CreateOneInputType } from '@ptc-org/nestjs-query-graphql';
import { AssetDTO } from '../asset.dto';
@InputType('CreateOneAssetInput')
export class CreateOneAssetInputDTO extends CreateOneInputType(
'asset',
AssetDTO,
) {
@Field(() => String)
filePath: string;
}
filePath
is used to create or lookup an associated entry, making my graphql schema look like this:
type CreateOneAssetInput {
asset: CreateAsset!
filePath: String!
}
The query service looks like:
export class AssetQueryService extends ProxyQueryService<
AssetEntity,
CreateOneAssetInputDTO
> {
fileRepository: Repository<FileEntity>;
constructor(
@InjectQueryService(AssetEntity)
service: QueryService<AssetEntity, CreateOneAssetInputDTO>,
@InjectRepository(FileEntity)
fileRepository: Repository<FileEntity>,
) {
super(service);
this.fileRepository = fileRepository;
}
async createOne(input: CreateOneAssetInputDTO): Promise<AssetEntity> {
const { filePath } = input;
const file = await this.fileRepository
.createQueryBuilder()
.insert()
.into(FileEntity)
.orIgnore()
.values({
location: filePath,
})
.updateEntity(false)
.execute();
// ... more stuff
return this.proxied.createOne(input);
}
}
The problem I'm having is input: CreateOneAssetInputDTO
in createOne
is delivered as AssetDTO
rather than the whole input argument ({ asset: ..., filePath: ... }
).
Am I going about this the right way? As always your help is appreciated!
I am trying to write a custom CreateOne Mutation for one of the entities. What is the way to do that? Looking at documentation https://tripss.github.io/nestjs-query/docs/graphql/resolvers#createresolver it't not very clear how can i do that? Can this be described a little more?