typescript - Hvordan skubber man et element til et array i et MongoDB-dokument på Nest.js?


Jeg føler mig ekstremt dum over at stille dette spørgsmål, men det er første gang, jeg arbejder med Typescript generelt og Nest.js i særdeleshed. Jeg arbejder med Nest, MongoDB (gennem Mongoose) og Express.js.

Jeg har to modeller: Bruger og Indlæg. Til dette ville den relevante være Bruger:

import * as Mongoose from 'mongoose';

export const UserSchema = new Mongoose.Schema(
  {
    username: { type: String, required: true },
    posts: { type: [Mongoose.SchemaTypes.ObjectId], ref: 'Post' },
    favs: { type: [Mongoose.SchemaTypes.ObjectId], ref: 'Post' },
  },
  {
    timestamps: true,
  },
);

Jeg laver en API til en Twitter-lignende app, hvor en bruger kan oprette opslag og tilføje dem til Favoritter. Jeg følger vejledninger, som man gør, når man er ny med en teknologi, men jeg har svært ved at se, hvordan man tilføjer en ny favorit til brugerens favoritter. Her er User-controlleren indtil videre:

import {
  Controller,
  Get,
  Req,
  Res,
  HttpStatus,
  Put,
  NotFoundException,
  Param,
} from '@nestjs/common';
import { UserService } from './user.service';
import { Request, Response } from 'express';
import { CreateUserDTO } from './dto/create-user.dto';

@Controller('user')
export class UserController {
  constructor(private userService: UserService) {}

  //fetch an user
  @Get('userfavs/:userID')
  async getCustomer(@Res() res: Response, @Param('userID') userID: string) {
    const user = await this.userService.getUser(userID);

    if (!user) throw new NotFoundException('This user does not exist!');

    return res.status(HttpStatus.OK).json({
      username: user.username,

      favs: user.favs,
    });
  }

  @Put('addfav/:favID')
  async updateUser(
    @Req() req: Request,
    @Res() res: Response,
    @Param('favID') favID: string,
    @Body() createUserDTO: CreateUserDTO,
  ) {
    const user = await this.userService.updateUser(req.user._id, createUserDTO);
    if (!user) throw new NotFoundException('This user does not exist!');
    return res.status(HttpStatus.OK).json({
      message: 'Fav added successfully!',
    });
  }
}

Og servicen:

import { Injectable } from '@nestjs/common';
import { Model } from 'mongoose';
import { InjectModel } from '@nestjs/mongoose';
import { User } from './interfaces/user.interface';
import { CreateUserDTO } from './dto/create-user.dto';

@Injectable()
export class UserService {
  //creates Mongoose model for the User
  constructor(@InjectModel('User') private readonly userModel: Model<User>) {}

  //fetch a specific user - this will be useful to check favs
  async getUser(userID: string): Promise<User> {
    const user = await this.userModel
      .findById(userID)
      .populate('favs')
      .exec();
    return user;
  }

  //edit an specific user
  async updateUser(
    userID: string,
    createUserDTO: CreateUserDTO,
  ): Promise<User> {
    const updatedUser = await this.userModel.findByIdAndUpdate(
      userID,
      createUserDTO,
      { new: true },
    );
    return updatedUser;
  }
}

I Node.js ville jeg have gjort sådan:

User.findByIdAndUpdate(req.user._id, {
        $push: { favs: favId },
      })

Men i Nest kaster DTO'en mig ud af kurs.

Svar #1

Med NestJS kan du hente dit dokument fra Mongo med en find-operation (find, findById, findOne osv.). Derefter kan du ændre det objekt og gemme det. Du kan sende dit favId til din service fra din controller i stedet for DTO'en. I din service:

async updateUser(
  userID: string,
  favId: string
): Promise < User > {
  const user = await this.userModel.findById(userID).exec();
  if (!user) {
    throw new NotFoundException();
  }

  user.favs.push(favId);
  return user.save();
}