Obtain a nested array of objects from Mongoose's Model.find() method and then make modifications to the inner array

I need to retrieve an array of objects with a specific ID from my database within a server route, and then update a property of an object within that array (rather than returning just the objectID, I want to return the Document as an object with the specified ID).

Below is the code I've written for this task:

        let orders = await Order.find({restaurant: restaurantID, status: 'PROCESSING'})

        for(let order of orders){   //iterate through all orders
            for(let element of order.dishes){     //iterate through order.dishes array (called 'element' since the array contains objects)
                let dish = await Dish.findOne({_id: element._id})
                element['dish'] = dish  //create new property for the dish object
                delete element._id      //remove the ID property since it already exists inside the element.dish object
            }
        }

Each order object within orders includes an array named dishes, which holds objects with the properties amount and an id. To make it more manageable for the frontend, I aim to remove the ID property, replacing it with a new property called 'dish', holding the referenced dish object.

The challenge lies in manipulating the content of the orders array. While inspecting orders by converting it to JSON and sending it in the response, I obtain a JSON array of order objects. However, when I implement the provided code snippet, it fails to alter anything within my orders.

During debugging, the elements within my for loops appear as follows:

EmbeddedDocument {__parentArray: Proxy, __index: 0, $__parent: model, $__: InternalCache, $isNew: false, …}
. Upon conversion to JSON, the desired output is achieved:
{"amount":1,"_id":"6183b84fec1c3e109a2271be"}
.

Is orders truly an array in this scenario? If not, what would be the most efficient way to manipulate it or obtain the documents as an array?

The following represents how orders appears while being monitored in the debug window:

price (get):ƒ () {\n        return this[getSymbol].call(this.$__[scopeSymbol] || this, path);\n      }
price (set):ƒ (v) {\n        this.$set.call(this.$__[scopeSymbol] || this, path, v);\n      }
restaurant (get):ƒ () {\n        return this[getSymbol].call(this.$__[scopeSymbol] || this, path);\n      }
restaurant (set):ƒ (v) {\n        this.$set.call(this.$__[scopeSymbol] || this, path, v);\n      }
status (get):ƒ () {\n        return this[getSymbol].call(this.$__[scopeSymbol] || this, path);\n      }
status (set):ƒ (v) {\n        this.$set.call(this.$__[scopeSymbol] || this, path, v);\n      }
timestamp (get):ƒ () {\n        return this[getSymbol].call(this.$__[scopeSymbol] || this, path);\n      }
timestamp (set):ƒ (v) {\n        this.$set.call(this.$__[scopeSymbol] || this, path, v);\n      }
user (get):ƒ () {\n        return this[getSymbol].call(this.$__[scopeSymbol] || this, path);\n      }
user (set):ƒ (v) {\n        this.$set.call(this.$__[scopeSymbol] || this, path, v);\n      }
__v (get):ƒ () {\n        return this[getSymbol].call(this.$__[scopeSymbol] || this, path);\n      }
__v (set):ƒ (v) {\n        this.$set.call(this.$__[scopeSymbol] || this, path, v);\n      }
__proto__:Model
length:1

In Postman, the response body looks similar to the desired format but only contains the id instead of the full dishes object:

[
    {
        "_id": "6183b84fec1c3e109a2271bd",
        "user": "6166bc426181646198fc483c",
        "restaurant": "6176947ce8b10986b018930e",
        "dishes": [
            {
                "amount": 1,
                "_id": "6183b84fec1c3e109a2271be"
            },
            {
                "amount": 2,
                "_id": "6183b84fec1c3e109a2271bf"
            }
        ],
        "price": 30,
        "status": "PROCESSING",
        "timestamp": "2021-11-04T10:39:11.800Z",
        "__v": 0
    }
]

If this issue has been addressed elsewhere, kindly share the link to the relevant question/answer. I have devoted several hours attempting to resolve this matter and have explored various questions without finding a suitable solution.

Answer №1

Many people often find themselves puzzled when they realize they can't change the data retrieved from MongoDB.

The reason behind this is Mongoose's peculiar behavior; instead of simple JSON, it returns a set of Mongoose objects. These objects come with additional methods like .save(), but most importantly, their nested objects are unchangeable. Simply modifying their properties will not have any impact.

To make modifications to the data returned by Mongoose, you have two options:

  1. Utilize .markModified()

It may seem strange at first, but changes made will only take effect once marked as modified. For example:

element['dish'] = dish;
order.save();

This alteration will not reflect in Mongo. You need to use .markModified():

element['dish'] = dish;
order.markModified("dishes");
order.save(); // It now works :|
  1. Instruct Mongoose to provide straightforward JSON output

By using .lean(), you can prevent Mongoose from creating its own objects and instead receive simple JSON data that can be modified freely.

let orders = await Order
           .find({restaurant: restaurantID, status: 'PROCESSING'})
           .lean()
           .exec(); // Don't forget to add .exec(), ensuring a true Promise is returned 

Additional tip: lean() offers better performance and efficiency.

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

Tips on implementing live updates in Firebase without the need for reloading the page

After a user changes their profile picture, the update does not appear until they refresh the page. Here is the code snippet causing this issue: const handleProfile = async (e: any) => { const file = e.target.files[0] const storageRef = firebase ...

Sending the results from a Vue.js component to a text input field in HTML

Using vue.js and the v-for function to read QR codes has been a challenge for me. For example: <ul v-for="(scan,key) in scans" :key="key" > {{scan.content}} </ul> I need to extract the value inside {{scan.content}}, like an EmployeeID, but I ...

Error encounter when loading the chunk for FusionCharts's overlappedbar2d.js in React.js: fusioncharts.overlapped

Currently, I am working on a web application that utilizes next.js and FusionCharts. Within the app, various FusionChart types have already been set up. My task now is to integrate the Overlapping Bars chart as outlined in the following documentation: How ...

After repeated attempts to initialize and destroy, Froala encounters issues when loading a textarea via Ajax

Whenever an EDIT button is clicked to update some Blog Data, it triggers an Ajax call that brings up a textarea for Froala and initiates the initialization process. This sequence works smoothly initially, but after a few cycles of edit/submit (1, 2, or 3 o ...

Utilizing async await to manage Promise { <Pending> } with an Express API

I have an API controller that retrieves a list of doctors: exports.doctorsList = async (req, res) => { const users = await User.find().exec(); let responseArray = await users.map(async (user) => { const transactions = await MedicalCon ...

Cannot utilize the subscribed output value within the filter function

I am in need of assistance with my Angular 7 project. I have successfully implemented a service to call a Json file and output an object array. However, I am facing an issue when trying to filter the objects in the array based on a specific property called ...

How can I manipulate static files in Node/Express while still being able to access req.params?

Just starting out with node/express, and I may be overlooking an obvious solution. I came across a middleware for transforming static content: https://www.npmjs.com/package/connect-static-transform/. The transformation function is as follows: transform: ...

Encountering an issue with the Jade Template Engine while utilizing a layout option

I am currently working on an application where I want the sidebar navigation to remain consistent across all pages. To avoid redundancy, I plan to create the navigation in the layout file and then include it in other jade files. Below is the content of th ...

In which situations is it required to specify the return type of a function in TypeScript?

When it comes to making functions in typescript, the language can often infer the return type automatically. Take for instance this basic function: function calculateProduct(x: number, y: number) { return x * y; } However, there are scenarios where dec ...

Using angular.js variables in the script tag: A step-by-step guide

Currently, I am working on a project that involves displaying elements on a view using Angular.js and attempting to connect these DOM elements using jQuery connections. While the elements are being displayed correctly, I am encountering an issue when tryin ...

Angular form displayed on the screen

I'm having trouble finding a solution to this issue, as the form data is not being output. var app = angular.module('myApp', []); app.controller('mainController', ['$scope', function($scope) { $scope.update = funct ...

"Learn the process of setting a variable in ng-model within an input field based on a specific condition

I need to dynamically assign an ng-model variable based on a condition. For instance: <input type="text" ng-model="item.model[multilang]" > The $scope.multilang variable can be set to either "ENG", "JP" (languages) or false. So, when multilang = "E ...

I am facing difficulties in retrieving data from MongoDB using Angular 8

Having trouble loading data from MongoDB using Angular 8? I've successfully loaded data with https://jsonplaceholder.typicode.com/, but when trying locally at 'http://localhost:3000/employees', it doesn't work. I can post data but una ...

Merging a VUE project and a .NET framework project to unleash their full potential

Currently, I am working on a project that involves using VUE for the client side and .net framework for the server side. However, these two components are hosted as separate projects, requiring me to open different ports during development. I am aware tha ...

Hiding a pop-up element and updating the state to False when clicking anywhere outside the element in the background

Presented here is my Search.js component. class Search extends Component { state = { doctors: [], showTab: false } openTab = () => { this.setState({showTab: true}); console.log('openTab state', this ...

React: maintaining referential equality across renders by creating closures with useCallback

I want to make sure the event handling function I create in a custom hook in React remains referentially equal across renders. Is it possible to achieve this using useCallback without specifying any variables it closes over in the dependencies list? Will o ...

Utilizing the splice method across multiple instances of a string

When facing a string like "This website is blocked by administrator. Please get the admin permissions. You will be allowed only if permission is granted" that needs to be split into three lines for better readability, one solution is using the splice metho ...

Encountering AJAX Error 0 with jQueryUI Autocomplete upon pressing enter key

Currently, I am facing an issue with a search box that utilizes the jqueryUI .autocomplete feature to retrieve data through AJAX for providing suggestions. The problem arises when a user presses the enter key before the AJAX call to the source completes, r ...

Vercel does not support Angular-router

I am currently working on deploying my serverless web MEAN application using Vercel. I have encountered an issue where accessing a route through the navigation menu works fine, but when trying to access the same route directly via http://vercel-dev/some- ...

When a barcode scanner is used, it will trigger a "keypress" event only if the user is currently focused on an input box. Is there a specific event to monitor when the user is not on an input

Scenario: In the development of my web application, I am utilizing a barcode scanner device that allows users to scan barcodes for navigation to specific pages. Challenge: The current barcode scanning device is set up to only trigger "keypress" events w ...