Ошибка проверки: приведение к массиву не удалось для значения - PullRequest
0 голосов
/ 10 апреля 2020

Я пытаюсь использовать Тип goose с GrqphQL, MongoDB и Nest. js. Я хотел создать мутацию, которая создаст пост. Я создал модель, сервис и резольвер для простого Post . Когда я пытаюсь запустить свою мутацию для создания сообщения, я получаю эту ошибку:

Ошибка проверки PostModel: разделы: Ошибка приведения к массиву для значения:

[
  [Object: null prototype] {
    title: 'section 1',
    body: [ 'section test lalal' ],
    code: [ "console.log('hello world!)" ],
    image: [ 'kanow.svg' ]
  }
]

при path "section"

Я не знаю, почему я получаю эту ошибку, которую я пытался использовать: ref , itemsRefs (для значения класса и строки. Вы можете прочитать больше об этом здесь: type goose arrayProp ). После создания новых PostModel и каждого console.log каждого свойства я вижу, что sections является пустым массивом, но не должен, потому что внутри postInput я могу найти это JSON:

[Object: null prototype] {
  title: 'refactored post',
  image: 'rest.jpg',
  tags: [ 'ref, ref' ],
  sections: [
    [Object: null prototype] {
      title: 'section 1',
      body: [Array],
      code: [Array],
      image: [Array]
    }
  ]
}

Я думаю, это json выглядит хорошо, поэтому оно не должно быть источником этой ошибки.

Я хочу знать, что я делаю неправильно, и почему это не работает. Ниже я приложил некоторый код. Если вам нужно что-то еще, дайте мне знать в комментариях.

Мутация GraphQL :

mutation {
  createPost(postInput: {
    image: "rest.jpg",
    title: "refactored post"
    tags: ["ref, ref"]
    sections: [{
      title: "section 1"
      body: ["section test lalal"]
      code: ["console.log('hello world!)"]
      image: ["kanow.svg"]
    }]
  }) {
    _id
    title
    tags
    sections {
      title
      body
      code
      image
    }
  }
}

post.service.ts :

@Injectable()
export class PostsService {
    constructor(@InjectModel(PostModel) private readonly postModel: ReturnModelType<typeof PostModel>) {
    }

    async create(postInput: CreatePostInput): Promise<DocumentType<PostModel>> {
        const createdPost: DocumentType<PostModel> = new this.postModel(postInput);
        return await createdPost.save();
    }
 ...
}

post.model.ts :

@ObjectType()
export class PostModel {
    @Field(() => ID)
    readonly _id: ObjectId;

    @Field()
    @prop({required: true})
    title: string;

    @Field()
    @prop({nullable: true})
    image: string;

    @Field(() => [String])
    @arrayProp({items: String})
    tags: string[];

    @Field(() => [SectionModel])
    @arrayProp({ref: 'SectionModel'})
    sections: Ref<SectionModel>[];
}

section.model.ts :

@ObjectType()
export class SectionModel {
  @Field()
  @prop({ required: true })
  title: string;

  @Field(() => [String])
  @arrayProp({ items: String })
  body: string[];

  @Field(() => [String])
  @arrayProp({ items: String })
  code: string[];

  @Field(() => [String])
  @arrayProp({ items: String })
  image: string[];
}

create-post.input.ts :

@InputType()
export class CreatePostInput {
  @Field()
  readonly title!: string;

  @Field()
  readonly image!: string;

  @Field(() => [String])
  readonly tags!: string[];

  @Field(() => [CreateSectionInput])
  readonly sections!: CreateSectionInput[];
}

ОБНОВЛЕНИЕ 1

Я обнаружил, что если я пропущу пустой массив внутри тела разделов, то есть нет проблем создать пост. Я прилагаю пример запроса ниже:

mutation {
  createPost(postInput: {
    image: "newly created.jpg",
    title: "newly created"
    tags: ["newly created, ref"]
    sections: []
  }) {
    _id
    image
    title
    tags
    sections {
      title
      body
      code
      image
    }
  }
}

1 Ответ

0 голосов
/ 12 апреля 2020

Я понял, что не должен использовать Ref<> для объявления вложенных документов. Для этого вам необходимо использовать items и указать правильный тип goose class model. В документации вы можете прочитать, что элементы предназначены только для примитивных типов, но в конце описания items документации вы можете прочитать, что вы можете использовать его также для тип goose классы (например SectionModel.ts). Ниже я привел пример, который решает мою проблему.

post.model.ts:

@ObjectType()
export class PostModel {
  @Field(() => ID)
  readonly _id: ObjectId;

  @Field()
  @prop({required: true})
  title: string;

  @Field()
  @prop({nullable: true})
  image: string;

  @Field(() => [String])
  @arrayProp({items: String})
  tags: string[];

  @Field(() => [SectionModel])
  @arrayProp({items: SectionModel})
  sections: SectionModel[];
}

section.model.ts:

@ObjectType()
export class SectionModel {
  @Field(() => ID)
  readonly _id: ObjectId;

  @Field()
  @prop({ required: true })
  title: string;

  @Field(() => [String])
  @arrayProp({ items: String })
  body: string[];

  @Field(() => [String])
  @arrayProp({ items: String })
  code: string[];

  @Field(() => [String])
  @arrayProp({ items: String })
  image: string[];
}
...