skip to Main Content

My route is below:

export async function GET() {
   await connectMongoDB();
   const allCargoDetails = await CargoDetails.find();
   return NextResponse.json({ allCargoDetails });
}
    
export async function DELETE(request) {
   const id = request.nextUrl.searchParams.get("id");
    
   await connectMongoDB();
   await CargoDetails.findByIdAndDelete(id);
   return NextResponse.json({ message: "Detaily smazány" });
}

Here I remove an object from Mongo DB:

const RemoveCalculations = ({ id }) => {
   const router = useRouter();
   const removeCalculations = async () => {
     const confirmed = confirm("Opravdu chcete vymazat tyto data?");
    
     if (confirmed) {
       const res = await fetch(
         `http://localhost:3000/api/cargoDetails?id=${id}`,
         {
           method: "DELETE",
         }
       );
       if (res.ok) {
         router.push("/calculations/activeCalculations");
         router.refresh();
       }
     }
   };
   return (
     <ImBin
       size={25}
       onClick={removeCalculations}
       className="text-red-500 cursor-pointer"
     />
   );
};
    
export default RemoveCalculations;

My collection:

{
    "allCargoDetails": [
        {
            "_id": "66621291950c30414c686370",
            "defaultValues": [
                 {
                    "count": 1212,
                    "long": 1212,
                    "high": 1212,
                    "width": 1212,
                    "weight": 1212,
                    "_id": "66621291950c30414c686371"
                 },
                 {
                    "count": 12,
                    "long": 12,
                    "high": 12,
                    "width": 12,
                    "weight": 12,
                    "_id": "66621291950c30414c686372"
                 }
             ],
             "client": "Hella",
             "sdl": "SDL#10476543",
             "price": 13131313,
             "createdAt": "2024-06-06T19:48:33.956Z",
             "updatedAt": "2024-06-06T19:48:33.956Z",
             "__v": 0
         }
     ]
}

In my code above, I removed an entire collection from the database by id. But I can’t figure out how to remove the nested array inside defaultValues by id.

Any advice would be greatly appreciated.

2

Answers


  1. Chosen as BEST ANSWER
    export async function DELETE(request) {
      const id = request.nextUrl.searchParams.get("id");
      const nestedId = request.nextUrl.searchParams.get("nestedId");
    
      const result = await CargoDetails.findOneAndUpdate(
        {
          $and: [
            { _id: mongoose.Types.ObjectId(id) },
            {
              defaultValues: { $elemMatch: { _id: mongoose.Types.ObjectId(_id) } },
            },
          ],
        },
        {
          $pull: {
            "allCargodetails.$.defaultValues": {
              count,
              long,
              width,
              weight,
              high,
              _id: nestedId,
            },
          },
        },
        { new: true }
      );
      return NextResponse.json({ message: "Data upravena" }, { status: 200 });
    }
    

    I tried update my code like below, but i think I am doing it wrong way, because I still remove entire collection

    const RemoveCalculations = ({ id, nestedId }) => {
          const router = useRouter();
          const removeCalculations = async () => {
            const confirmed = confirm("Opravdu chcete vymazat tyto data?");
        
            if (confirmed) {
              const res = await fetch(
                `http://localhost:3000/api/cargoDetails?id=${id}&nestedId=${nestedId}`,
                {
                  method: "DELETE",
                }
              );
              if (res.ok) {
                router.refresh();
              }
            }
          };
          return (
            <ImBin
              size={25}
              onClick={removeCalculations}
              className="text-red-500 cursor-pointer"
            />
          );
        };
        
        export default RemoveCalculations;
    

  2. This can be done in different ways and I wanted to explain some of them:

    The first way, we can use findByIdAndUpdate since we already have the document’s id. Then, for removing the related object, need to use the $pull operator with the all positional operator $[] to remove all elements that are matched. If we knew the index of the related element, then using (e.g. if the index is 1) allCargoDetails.1.defaultValues would handle it but we don’t know the index:

    export async function DELETE(request) {
      const id = request.nextUrl.searchParams.get("id");
      const nestedId = request.nextUrl.searchParams.get("nestedId");
    
      const result = await CargoDetails.findByIdAndUpdate(
            { _id: mongoose.Types.ObjectId(id) },
            {
               $pull: {
                 "allCargoDetails.$[].defaultValues": { _id: nestedId }
               }
            },
            { new: true }
      );
    
      return NextResponse.json({ message: "Data upravena" }, { status: 200 });
    }
    

    Another way is if we know which allCargoDetails element we want to work on, then find the related element by using this element’s information like _id. For that, need to use the findOneAndUpdate method. Also, use the positional operator $ to match hand pull the first matched object in the array. We use the positional operator $ here instead of the all positional operator $[] since we already know which allCargoDetails array we need to work on and we found it by matching its id. Therefore, we just need to find the first matched element in this matched allCargoDetails array:

    export async function DELETE(request) {
      const id = request.nextUrl.searchParams.get("id");
      const nestedId = request.nextUrl.searchParams.get("nestedId");
    
      const result = await CargoDetails.findOneAndUpdate(
            { 
               _id: mongoose.Types.ObjectId(id), 
               "allCargoDetails._id": "66621291950c30414c686370" 
           },
           {
               $pull: {
                 "allCargoDetails.$.defaultValues": { _id: nestedId }
               }
           },
           { new: true }
      );
    
      return NextResponse.json({ message: "Data upravena" }, { status: 200 });
    }
    

    I also created a DEMO LINK for you to review and test easily.

    Hope, it’s clear and helpful

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search