What is the best way to transform these nested callback-heavy functions into async await or promises?

I'm relatively new to Node.js and I need to execute a series of functions one after the other, as they are interdependent. Initially, I opted for the callback function approach where I invoked another callback, essentially creating nested callbacks in sequential order to achieve the desired outcomes.

However, at some point, I came across the concept of Callback Hell and realized that it should be avoided. This left me perplexed about how to utilize promises/ async-await to accomplish the same goal.

Furthermore, I'm puzzled about how promises differ from nested callbacks, considering that in promises, the subsequent promise is executed only after the previous promise is resolved, indicating a similar nested nature.

If anyone could provide guidance on where I might be mistaken, I would greatly appreciate it.

    router.route('/addTasks-approve').get(function(req, res) {
    
if(req.query.text == 'Approved')
                     {
                      User.updateMany({'Addtasks.commonID':req.query.id},
                         {$set: {"Addtasks.$.width" :'250px',
                          "Addtasks.$.height" :'32px',
                          "Addtasks.$.background" :'linear-gradient(45deg, #0f3443, #34e89e)',
                          "Addtasks.$.border_radius" :'10px / 5px',
                         "Addtasks.$.status" :req.query.text}},
                        function (error, success) {
                              if (!error) {
                                console.log("Approved color set!");
                                User.findOne({tag:'Admin','Addtasks.commonID':req.query.id},function (error, dataAdmin) {
                                      if (error) {
                                          console.log("error = "+ error);
                                          res.end('{"msg" : "Some error occurred", "status" : 700}');
                                      }
                                      else {
                                        dataAdmin.Addtasks.forEach(element => {
                                          if(element.commonID == req.query.id)
                                          {
                                     User.findOneAndUpdate({tag:'Client','Addtasks.commonID':req.query.id},
                                     {$push: {'Addtasks.$.Bigpaths4Clients':{$each : element.Bigpaths4Clients}},
                                      $set: {"Addtasks.$.background" :'linear-gradient(45deg, #1E6305, #BDFF00)',
                                             "Addtasks.$.status" :'Done'}},
                                        function (error, data) {
                                              if (error) {
                                                console.log("error = "+ error);
                                                res.end('{"msg" : "Unable to add the Task", "status" : 700}');
                                              }
                                              else {
                                                console.log("Addtasks added to Client's dashboard succesfully");
                                                sendMails2Client(data.email, element.topic, 'In Progress', 'Done');
                                                sendMails2User(dataAdmin.email, element.topic, 'Done', 'Approved');
                                                User.findOne({tag:'Admin','Addtasks.commonID':req.query.id},function (error, dataWriter) {
                                                      if (error) {
                                                          console.log("error = "+ error);
                                                          res.end('{"msg" : "Some error occurred", "status" : 700}');
                                                      }
                                                      else {
                                                        sendMails2User(dataWriter.email, element.topic, 'Done', 'Approved');
                                                        res.end('{"success" : "success", "status" : 200}');
                                                      }
                                                    })
                                              }
                                      })
                                    }
                                  });
                                }
                              });
                              }
                              else {
                                res.end('{"msg" : "Unable to set the status and color for Approved", "status" : 700}');
                              }
                            });
                          }                 
})

Answer №1

Check out this informative article comparing Callback, Promise, and async/await with examples... I personally prefer using async/await

Your code snippet showcasing the use of async/await:

router.route("/addTasks-approve").get(async (req, res) => {
  if (req.query.text == "Approved") {
      try {
        let resUpdate = await User.updateMany(
            { "Addtasks.commonID": req.query.id },
            {
              $set: {
                "Addtasks.$.width": "250px",
                "Addtasks.$.height": "32px",
                "Addtasks.$.background": "linear-gradient(45deg, #0f3443, #34e89e)",
                "Addtasks.$.border_radius": "10px / 5px",
                "Addtasks.$.status": req.query.text,
              },
            }
          );
            console.log("Approved color set!");
            let dataAdmin = await User.findOne({
              tag: "Admin",
              "Addtasks.commonID": req.query.id,
            });
      
            dataAdmin.Addtasks.forEach(async (element) => {
              if (element.commonID == req.query.id) {
                let data = await User.findOneAndUpdate(
                  { tag: "Client", "Addtasks.commonID": req.query.id },
                  {
                    $push: {
                      "Addtasks.$.Bigpaths4Clients": {
                        $each: element.Bigpaths4Clients,
                      },
                    },
                    $set: {
                      "Addtasks.$.background":
                        "linear-gradient(45deg, #1E6305, #BDFF00)",
                      "Addtasks.$.status": "Done",
                    },
                  }
                );
      
                console.log("Addtasks added to Client's dashboard successfully");
                await sendMails2Client(data.email,element.topic,"In Progress","Done");
                await sendMails2User(dataAdmin.email,element.topic,"Done","Approved");
                let dataWriter = await User.findOne({
                  tag: "Admin",
                  "Addtasks.commonID": req.query.id,
                });
                await sendMails2User(dataWriter.email, element.topic, "Done", "Approved");
                res.end('{"success" : "success", "status" : 200}');
              }
            });
      } catch (error) {
          console.log(error)
      }
    
  }
});

Remember to implement error handling using try/catch for any potential error occurrences in your code

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

Encountering error while running npm ci: 'Error reading property '@angular/animations' as undefined'

During the docker build process of my Angular project, I encountered an error while running the npm ci command: Cannot read property '@angular/animations' of undefined Despite the lack of a clear explanation in the error message, we have been st ...

Having trouble generating package.json with npm init on my Mac

Every time I attempt to generate a package.json file by using the command npm init, I encounter the following issue: npm http GET https://registry.npmjs.org/init npm http 304 https://registry.npmjs.org/init npm http GET https://registry.npmjs.org/daemon n ...

Comparing NodeIntegration, Preload Script, and IPC in Electron Framework

After thoroughly going through Electron's explanations on context isolation, IPC, and security, as well as delving into discussions like this thread about nodeIntegration and this post regarding preload.js, it's clear that there are various appro ...

creating a while loop in node.js

In C#, the following code would be used: double progress = 0; while (progress < 100) { var result = await PerformAsync(); progress = result.Progress; await Task.Delay(); } This concise piece of code spans just 7 lines. Now, how can we ...

Error encountered in Visual Studio while working on a Node.js project: "The specified path or filename is too lengthy."

Whenever I set up a Blank Express Application in Visual Studio 2013 and launch it post installing npm modules, everything runs smoothly without any errors. But if I close the solution and reopen it later, the project fails to load with errors appearing in ...

Is there a way to efficiently clear the Express session for all users without the need to restart the application?

During my development of REST services using the nodejs express framework, I encountered an issue with storing user-specific data in sessions. I utilized the user's ID as a key to identify the user's data. The following code snippet demonstrates ...

Error extracting geographical keys from mongoose schema with geojson data

My mongodb collection had a specific schema, but I recently made an update to include lat/lon coordinates. Original version: var schema = mongoose.Schema({ id: String, name: String, address: String, city: String, zip: String, coun ...

Unable to update values in Google Sheets using the node.js API

I have been working on a node.js project that involves extracting the location of a cell based on a person's name and date. While I am able to determine this information easily, I encounter difficulties when trying to update the cell using the .update ...

Guide on allowing a parent module to import a sub-module within another module in NodeJS

Module X │ └─ Module Y (devDependency in Module X's package.json) │ └─ Module Z (dependency in Module Y's package.json) Module Y is the focus of my current development efforts. However, I am aware that module Z will be called w ...

Using Mongo Node Angular all in one server

Is it advisable to host Angular, Node-express, and Mongo on the same server, such as localhost:3000 or somehosting.com/server-address? Would this be considered a best practice? I have seen Angular and Node running together on the same server, but what abo ...

Tips for incorporating dynamic URLs in Next.js

In my current project using nextjs, I am dealing with fetching images via an API. Right now, I am receiving the "Full image path" (for example, "https://myurl.com/image/imagename.jpg") without any issue. However, I need to figure out how to fetch the image ...

mongoose: uniqueness constraint not being enforced

I am currently seeking information on how to ensure uniqueness for a field that is not an index. I have come across a similar question here, but the solution of using dropDups: true has been deemed outdated. What is the proper method for enforcing unique ...

The error message "TypeError: res.json is not a function in express.router" indicates that

I encountered the following error message and I'm not sure how to resolve it: TypeError: res.json is not a function I have reviewed the express documentation but couldn't find any syntax errors or issues. Here is my code: index.js import expr ...

Best practices for sending an object from client to server using Node.js

What is the best way to transfer a large object from client side to my node.js server? The object is currently stored in a variable within my script tags. ...

Querying the sqlite-3 database fails to transfer data to a JavaScript array

I encountered an issue while working on a NodeJS project that involves fetching film names and descriptions from an Sqlite-3 file when a user sends a GET request to /films. For some reason, I am unable to push the object to an array properly. Despite my ...

Updated the application to Angular 6 but encountered errors when attempting to run npm run build --prod. However, running the command npm run build --env=prod was executed without any issues

Running the command npm run build -- --prod results in the following error messages: 'PropertyName1' is private and can only be accessed within the 'AppComponent' class 'PropertyName2' does not exist in type 'AppCompo ...

Callback is triggered after ng-if removes the directive from the scope

A scenario on my page involves an angular directive nested within ng-if. I've developed a service that features a function, let's name it functionX, capable of accepting a callback as an argument. Whenever the ng-if condition becomes true, the ...

Anticipating the execution of pool.query within a callback function in the Express framework

Within an Express post endpoint, I am utilizing crypto.generateKeyPair. After generating the key pair, I wish to store it in my database and then return the ID of the inserted row within the same endpoint. Here is the code snippet for the endpoint: app.p ...

Parsing of CSS and Javascript is disabled within iframes

Within my node.js application, I have configured an endpoint where I can load some parsed HTML code. This is achieved through the following code: app.get('/code', function (req, res) { res.setHeader('Content-Type', 'text/html& ...

Error in client-sessions module of nodejs/Express: Unable to assign value to property 'mydata' as it is undefined

I've been experimenting with the client-sessions middleware in my nodejs / Express project and encountered an issue that says: Cannot set property 'mydata' of undefined. While researching this problem, I came across a post on Stack Overflow ...