Ways to transform a foreach loop into a promise-based operation

I have a function that recursively deletes nodes:

removeNode(data.toString())
function removeNode(node){
    Item.findByIdAndDelete(node).then(()=>{
        Item.find({parent: mongoose.Types.ObjectId(node)}).select('_id').then((nodes)=>{
            nodes.forEach(n => {
                removeNode(n._id)
            });
        })
    })
}

I want to convert this function into a promise so I can use it like this:

removeNode(data.toString()).then(()=>{console.log('deletion complete')})

Any suggestions on how I can achieve this promisification would be highly appreciated!

Answer №1

Best Practices:

  • Make sure to return every promise created within a callback function.
  • Utilize map instead of forEach when dealing with arrays of promises from recursive calls, and pass the resulting array to Promise.all.
  • Simplify the promise chain by avoiding nested then callbacks.
function remove(node) {
    return Item.findByIdAndDelete(node).then(() => {
        return Item.find({parent: mongoose.Types.ObjectId(node)}).select('_id');
    }).then(d => {
        return Promise.all(d.map(e => {
            return remove(e._id)
        }));
    });
}

Consider using async await for improved readability:

async function remove(node) {
    await Item.findByIdAndDelete(node);
    let d = await Item.find({parent: mongoose.Types.ObjectId(node)}).select('_id');
    return Promise.all(d.map(e => remove(e._id)));
}

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

Steps for incorporating a custom Knockout function in Typescript

I need to create an event binding for my observable array in order to trigger a function when the input (e.g., description) changes. I've looked at various solutions online but none of them seem to be working with Typescript. Below is the code I have: ...

A guide to implementing PDF.js within an Angular 2/4/5 application

I am currently working on creating a PDfViewer Application using Mozilla's PDF.js (see example here). I would greatly appreciate it if anyone knows of a Github project that I could use as reference. Thank you in advance! ...

Dividing a string into an array and displaying it in a table using Laravel

Retrieving a string from the database and using the explode function to split the values. Below is the code snippet: $data = DoctorRegistration::select('products') ->where('doctorid','=',$doctorid) ->get(); ...

Having difficulty scrolling down in a section with 100% height on iOS devices

Currently facing an issue with a website I am creating for my wedding invitation. The top section is set to have a 100% height and requires scrolling to view the rest of the content. While it functions perfectly on FireFox / Chrome on my computer, there s ...

Unable to locate module within a subdirectory in typescript

The issue I'm facing involves the module arrayGenerator.ts which is located in a subfolder. It works perfectly fine with other modules like Array.ts in the parent folder. However, when I introduced a new module called Sorting.ts, it started giving me ...

Once the "approve" button on a sales order is clicked, my intention is to generate a purchase order

When a user clicks the approve button on a sales order, I need to generate a purchase order. I have deployed a script to the sales order records with the event type set to trigger when the approve button is clicked. However, I am encountering an issue wher ...

Transforming jQuery into Angular - Press Button to update choices in Dropdown List

I am looking to integrate some AngularJS features into a website that currently utilizes jQuery. Here is the issue I am facing: With jQuery, clicking a button triggers a dropdown item change. Please refer to the jsfiddle below for an example: $('# ...

leveraging third party plugins to implement callbacks in TypeScript

When working with ajax calls in typical javascript, I have been using a specific pattern: myFunction() { var self = this; $.ajax({ // other options like url and stuff success: function () { self.someParsingFunction } } } In addition t ...

Exploring scroll functionality with Webdriver.io v4

My code is designed to log into the beta version of mediawiki, navigate to the Preferences page, and attempt to click on a button located at the bottom of the page. In order to achieve this, I am utilizing the scroll() function because using only .click() ...

Tips for overlaying text onto a canvas background image

I'm curious about how to overlay text on top of an image that is within a canvas element. The image is a crucial part of my game (Breakout), so it must remain in the canvas. I've tried adding text, but it always ends up behind the image, which is ...

Creating dynamic divs on button click for my project is something that I must do, and I will

When the user clicks on the Add button, a new div should be added as shown in the image above. Implementing this functionality using Bootstrap is crucial because the divs must rearrange correctly based on different resolutions such as 1920x900, 1280x600, ...

Adding a fresh selection to the Bootstrap menu

I'm working on a straightforward Bootstrap form that includes a select input: <div class="form-group"> <label for="category" class="control-label col-sm-3">Category</label> <div class="input-group col-xs-8"> <sele ...

Refining/searching with selectors in AJAX response

As someone who is new to javascript and coding in general, I am facing a challenge with filtering and manipulating data received through an AJAX request. Unfortunately, I do not have access to the server-side code. The server responds with rota information ...

Adding elements to the <Head> section in Next.js

I am facing an issue where I need to change the page title dynamically based on the route of the web pages. I have been assigned the task of creating and importing a title component into the layout file, but despite my efforts, nothing seems to change. con ...

Sending a file using Angular's $http service

I am facing an issue while trying to upload a form with an image file using the angular $http function and multer in the background for receiving. I have successfully uploaded the image via a direct form submission (without angular) as shown below: <fo ...

Why is jQuery not defined in Browserify?

Dealing with this manually is becoming quite a hassle! I imported bootstrap dropdown.js and at the end of the function, there's }($); Within my shim, I specified jquery as a dependency 'bootstrap': { "exports": 'bootstrap', ...

What is the best way to add a data value to a dynamically generated div element?

I've been struggling to link a data value with a dynamically created div, but so far I haven't had any success. I've searched online for solutions, but I can't find any examples that fit my specific issue. If anyone has any advice, I wo ...

Concealing the primary div within a Vue child component

Is there a way to conceal the primary div within a Vue application created using Vue-CLI? I attempted adding the display property, but it did not solve the problem. I am attempting to hide it within my Channels component. Here is how my main component lo ...

What is the best way to toggle a d3 svg overlay using a leaflet layer control?

I am looking for a solution to place 3 d3 svgs on a leaflet map and control them as easily as leaflet layers. Check out this code example, which works but is not ideal. The key part is from line 75 onwards, where I create a custom layer control linked to ...

Ways to prevent decreasing the value below zero in ReactJS?

I have created two buttons, one for increasing and another for decreasing a counter value. However, when I click on the minus button, it should not display negative values. But in my case, when I click on the minus button (initially at zero), it shows -1, ...