Sam
Sam

Reputation: 37

How to get a sum of an array in Nodejs using foreach?

I have an array/schema called "plants",and populating on a webpage. I want to get the sum of plant rates(last item). how can i do that in Nodejs?

Below is the template showing plants table with the data from schema:

<% project.plants.forEach(function(plant){ %>
                  <tr>

                     <td class="td14" ><%= plant.noplant %></td>
                     <td class="td15" ><%= plant.plantname %></td>
                     <td class="td16" ><%= plant.planthrperday %></td>
                     <td class="td17" ><%= plant.plantnodays %></td>
                     <td class="td18" ><%= plant.planthrrate %></td>
                     <td class="td19" ><%= plant.plantdep %></td>
                     <td class="td20" ><%= plant.plantrate %></td>
                     <td class="td21"><a href=""><button type="button" class="btn btn-danger">Remove</button></a></td>

                   </tr>
                <% }); %>

The route handler:

    app.get("/myprojects/:id/cost", function(req,res){

    Project.findById(req.params.id).populate("labours materials tools plants others").exec(function(err, foundProject){
        if(err){
            console.log(err);
            }else{
          res.render("cost", {project: foundProject});   
        }

    });

  });

Upvotes: 2

Views: 1736

Answers (2)

Fecosos
Fecosos

Reputation: 974

You can use reduce as follows:

const plantsRateSum = project.plants.reduce((accumulator, currValue) =>{
  return acumulator + currValue.plantrate;
}, 0);

Docs: Array.prototype.reduce()

Or in your particular case, calculate the sum after getting the plants array:

Project.findById(req.params.id).populate("labours materials tools plants others").exec(function (err, foundProject) {
  if (err) {
    console.log(err);
  } else {
    const plantsRateSum = foundProject.reduce((accumulator, currValue) => {
      return acumulator + currValue.plantrate;
    }, 0);
    res.render("cost", { project: foundProject, plantsRateSum: plantsRateSum });
  }
});

Upvotes: 4

Farhan Tahir
Farhan Tahir

Reputation: 2134

You can do this in template as I did below by declaring a variable plantRateSum and adding plantrate to that variable on every iteration of forEach

<% var plantRateSum = 0;  %>

<% project.plants.forEach(function(plant){ %>
          <% plantRateSum += plant.plantrate %> 
           enter code here
                  <tr>

                     <td class="td14" ><%= plant.noplant %></td>
                     <td class="td15" ><%= plant.plantname %></td>
                     <td class="td16" ><%= plant.planthrperday %></td>
                     <td class="td17" ><%= plant.plantnodays %></td>
                     <td class="td18" ><%= plant.planthrrate %></td>
                     <td class="td19" ><%= plant.plantdep %></td>
                     <td class="td20" ><%= plant.plantrate %></td>
                     <td class="td21"><a href=""><button type="button" class="btn btn-danger">Remove</button></a></td>

                   </tr>
                <% }); %>

But this would not be a good approach instead you should send sum of plant rates to template from route handler using reduce method like below:

const plantRateSum = project.plants.reduce(function(sum, plant){
  return sum + plant.plantrate;
}, 0);

Now pass this plantRateSum to template.

In your route handler do this:

 app.get("/myprojects/:id/cost", function(req,res){
    Project.findById(req.params.id).populate("labours materials tools plants others").exec(function(err, foundProject){
      if (err) {
        console.log(err);
      } else {
        var plantRateSum = foundProject.plants.reduce(function(sum, plant){
          return sum + plant.plantrate;
        }, 0); 
        res.render("cost", {project: foundProject, plantRateSum:plantRateSum});   
      }
    });
  });

Upvotes: 1

Related Questions