What is the process for adding an element to an array within a MongoDB document using Nest.js?

As a newcomer to Typescript and Nest.js, I'm feeling a bit lost in my project involving Nest, MongoDB with Mongoose, and Express.js. My main focus right now is on the User model:

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,
  },
);

I'm building an API for a Twitter-like app where users can create posts and add them to their Favorites. While following tutorials, I've hit a roadblock when it comes to pushing a new favorite post to a user's list. Here's what the User controller looks like so far:

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!',
    });
  }
}

And here's the service code:

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 - useful for checking favorites
  async getUser(userID: string): Promise<User> {
    const user = await this.userModel
      .findById(userID)
      .populate('favs')
      .exec();
    return user;
  }

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

In a Node.js environment, I would have approached this differently:

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

However, dealing with DTOs in Nest has been a bit confusing for me.

Answer №1

One of the great features of NestJS is its ability to easily fetch documents from MongoDB using operations like find, findById, findOne, and more. Once you have fetched an object, you can make modifications to it and save it back to the database. Instead of passing your favId through a DTO, you can directly pass it to your service from the controller. Here's how you can implement this in your 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();
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Implementing dynamic input attributes in Angular 5

Is there a way to dynamically add attributes to an input HTML element in Angular? This is the code from my component: import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-transclusion', templateUrl: &apo ...

Exploring the method of including a mat-chip-list within a form

Can't submit form with mat-chip-list elements, even though they are present. How to send the tag array? Please assist! View my form here Here is the code I have so far: <mat-form-field class="example-chip-list"> <mat-chip-list #c ...

Error: The function res.blob is not a valid function

How do I enable file download using the Angular 6 code below: Rest API: private static final Logger LOG = LoggerFactory.getLogger(DownloadsController.class); @GetMapping(path="export") public ResponseEntity<byte[]> export() throws IOException { ...

"Troubleshooting: Why is my jQuery ajax POST request displaying blank results

Expected Behavior 01 - When the form is submitted using jQuery. 02 - The authorization process should be completed. 03 - A MongoDB query needs to be executed. 04 - The results should be displayed instead of the form. Actual Behavior Steps 1 throug ...

Looking to segment data for better scalability?

Seeking a way to achieve write scaling, I made the decision to transform my standalone mongoDB into a sharded cluster. However, I am facing a challenge in finding a shard key with sufficient randomness to evenly distribute write operations across the clust ...

What is the best way to access dynamic URL parameters in the Next.js 13 app router from a nested server-side component?

This query pertains to the Server-Side components in Next.js 13 app router: I have a good grasp on how the slug parameter is passed to the default function in app/blog/[slug]/page.tsx: export default function Page({ params }: { params: { slug: string } }) ...

Having trouble reading the length property of undefined in Angular 7

Seeking to obtain a picture link of the object. The objects are stored in an array and the typescript method looks like this: getMealPicture(orderLineMeal: OrderLine): string { for (let meal of this.meals) { if (meal.id === orderLineMeal.mealId) ...

The current enablement status does not support the experimental syntax 'flow' (7:8):

Utilizing a Mono repo to share react native components with a react app has presented some challenges. When attempting to use a react native component from react, an error keeps popping up that I can't seem to resolve. I've attempted to follow t ...

Guide for adjusting icon dimensions in Material-UI breakpoints

import { Container } from "@mui/material"; import * as React from "react"; import { Home } from "@mui/icons-material"; import PersonIcon from "@mui/icons-material/Person"; import FormatListBulletedIcon from "@mu ...

The @Input() function is failing to display or fetch the latest value that was passed

I am currently working on an angular project, and I've encountered a situation where I'm attempting to send a value from a parent component to a child component using the @Input() decorator. Despite my efforts, the child component continues to di ...

The values entered in the React form inputs are not displaying accurately

I'm currently working on a project that involves creating a form for tours. Everything seems to be working well, except for the issue of input values getting mixed up. For example: Actual output: { tourName: 'pune darshan', location: &apos ...

Error encountered during decryption with AES encryption: 'ERR_OSSL_EVP_WRONG_FINAL_BLOCK_LENGTH'

I am attempting to decrypt data retrieved from MongoDB using a key and initialization vector (IV) that were stored in an environment function. However, I keep encountering the following error: ERR_OSSL_EVP_WRONG_FINAL_BLOCK_LENGTH app.get("/recieve", as ...

Check the test library to confirm that the aria-expanded value is set to false

I need assistance with testing a flyout component using test-library to verify the aria-expanded attribute value. After clicking on a flyoutItem, I want to ensure that the value of aria-expanded is set to false. Is there a more efficient way for me to ac ...

Issue with Angular Material date picker: Date Parsing UTC causing dates to display as one day earlier

After exploring numerous threads related to this issue and spending several days trying to find a solution, I may have stumbled upon a potential fix. However, the workaround feels too messy for my liking. Similar to other users, I am encountering an issue ...

Executing operations on subdocuments in Mongoose without having to fetch the parent

Currently, when I need to delete a subdocument, I follow this process: Post.findById(post_id).exec(function(err, post) { post.comments.remove({'_id': comment_id}); post.save(function(err) { res.end("Success!"); }); }); This method doe ...

Streamlining the process of transforming a struct into BSON and vice versa

When it comes to optimizing server performance, what is the best approach for converting a struct to bson or bson to struct? byteBson, err = bson.Marshal(&bsonData) if err != nil { panic(err) } err = bson.Unmarshal(byteBson, &user) if err != ...

The pipe operator in Angular is failing to function as intended

I encountered an error while using the replace operator in Angular. Can someone help me identify the issue? Check out this link for more information ...

Different ways to incorporate the div element with text content as opposed to images in ngx-slick-carousel

I am looking to incorporate multiple <div> elements with content into the ngx-slick-carousel in my Angular 12 application. Currently, the carousel is displaying placeholder images and I am unsure of how to replace these images with div elements. Her ...

What is the maximum transaction throughput that MongoDB can handle per second?

As I develop a new feature, I anticipate the need to execute hundreds or even thousands of MongoDB transactions for a specific endpoint. I am curious to know if MongoDB has a maximum limit on the number of transactions that can be processed? While researc ...

An issue occurred while attempting to access the `/blog` page in a next.js project

The Challenge: As I work on developing a blog using Next.js and Sanity, I am facing a browser error when trying to navigate to the /blog route. The specific error message reads as follows: ./sanity.js:2:0 Module not found: Can't resolve '@sanity ...