Search code examples
mongodbmongoosenext.js

Mongoose findByIdAndUpdate only finding and not updating


I'm using Mongoose findByIdAndUpdate to update the location field in this Mongoose schema:

import mongoose from "mongoose";

const UserSchema = new mongoose.Schema({
    userId: {
        type: String,
        required: true,
    },
    city: {
        type: String,
        required: true,
    },
    customerRating: {
        type: Number,
        required: true,
        default: 0,
    },
    businessName: String,
    businessRating: Number,
    bio: String,
    createdAt: {
        type: Date,
        required: true,
        default: () => Date.now(),
    },
    updatedAt: Date,
});


export default mongoose.models?.User || mongoose.model("User", UserSchema);

Here's my API route which houses the function:

import { User } from "@/mongo";
import { NextResponse } from "next/server";
import { z } from "zod";


export async function POST(request: Request) {
    const rawRequest = await request.json();
    const Schema = z.object({
        positionX: z.number().min(-180).max(180),
        positionY: z.number().min(-180).max(180),
        id: z.string()
    });
    const parsedRequest: RequestType = rawRequest;

    const valid = Schema.safeParse(parsedRequest);

    type RequestType = z.infer<typeof Schema>;

    if (!valid.success) {
        return NextResponse.json(
            { message: `Error: ${valid.error}` },
            { status: 400 }
        );
    }

    try {
        const response = await fetch("https://api.radar.io/v1/geocode/reverse?coordinates=33.5679,-117.7046", {headers: {"Authorization": "prj_live_sk_b9ef214e1d5f595b04dc6e32f5591d6c0952a611"}})


        const location = await response.json()

        const user = await User.findByIdAndUpdate (parsedRequest.id, {location: location.addresses.city})


       console.log(user)
        return NextResponse.json(
            { message: `Successfully updated user ${user._id}` },
            { status: 200 }
        );
    } catch (error) {
        return NextResponse.json({ message: `Error: ${error}` }, { status: 500 });
    }

}

When consoling it out I get:

{
  _id: new ObjectId("64e15e9d29617fb0163de01b"),
  userId: 'user_2RlEzQ822cDbhrbk1ohDYMui1ac',
  createdAt: 2023-08-20T00:30:21.946Z,
  __v: 0,
  business: { name: 'test' },
  customerRating: 1,
  businessName: 'tester 5'
}

So it clearly finds the object. I have also checked it manually and can confirm it does it exist. Why does it not update?


Solution

  • The findByIdAndUpdate method triggers the findOneAndUpdate() so as the docs state:

    By default, findOneAndUpdate() returns the document as it was before update was applied.

    You need to pass the {new:true} option like so if you want the document back after the update took place:

    const user = await User.findByIdAndUpdate(
       parsedRequest.id, 
       {city: location.addresses.city},
       {new: true} //< This option is important
    );