TypeORM: update item and return it

后端 未结 4 1458
感情败类
感情败类 2021-02-18 14:47

As far as I know, it\'s a best practice to return an item after it has been updated. TypeORM\'s updateById returns void, not the updated item though.

4条回答
  •  感情败类
    2021-02-18 15:09

    Although I want await Table.update({}, {}) to return Table it doesn't. I've found it easier to just work with the QueryBuilder because it gives me more control in general, BUT if you don't like the QueryBuilder or don't need it, you can do something like this:

    const post = await Post.update({id}, {...input}).then(response => response.raw[0]);
    return post; // returns post of type Post
    

    If you however do want to use QueryBuilder I suggest going with an approach like below. Others above has mentioned the usage of Repository and Table.save() Which doesn't really return the original type anywhere, so that approach is out of the picture for me.

    An example of QueryBuilder and Table.update({}, {}):

    @Mutation(() => PostResponse, { nullable: true })
    @UseMiddleware(isAuthorized)
    async updatePost(
      @Arg("id", () => Int) id: number,
      @Arg("input") input: PostInput,
      @Ctx() { req }: Context
    ): Promise {
    
      const { userId } = req.session;
      const errors = validatePost(userId, ...input, await Post.findOne(id));
    
      if (errors) {
        return { errors };
      }
      // THIS
      const post = await Post.update({id}, {...input}).then(response => response.raw[0]);
      // OR THIS (depending on what approach you want to use)
      const post = await getConnection()
        .createQueryBuilder()
        .update(Post)
        .set({ ...input })
        .where('id = :id and "creatorId" = :creatorId', {
          id,
          creatorId: userId,
        })
        .returning("*")
        .execute()
        .then((response) => {
          return response.raw[0];
        });
    
      return { post };
    }
    

    The key is returning response.raw[0] in order to get the type back.


    I've abstracted the results into a Response class, that is why I return different things here. Added for clarity

    @ObjectType()
    class FieldError {
      @Field()
      field!: string;
      @Field()
      message!: string;
    }
    
    @ObjectType()
    export class PostResponse {
      @Field(() => [FieldError], { nullable: true })
      errors?: FieldError[];
    
      @Field(() => Post, { nullable: true })
      post?: Post;
    }
    

    Note: I'm using TypeORM and Type-GraphQL here.

    .returning("*") does not work on MySQL, see comments below.

提交回复
热议问题