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?
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
);