1

import {
  Component,
  OnInit
} from "@angular/core";
import {
  MarkService
} from "../app/services/marks.service";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.scss"]
})
export class AppComponent implements OnInit {
  title = "my-test";
  public students = [];
  allStudents: any = [];
  average: any = [];

  constructor(private _marksService: MarkService) {}

  ngOnInit() {
    this._marksService.getMarks().subscribe(data => (this.students = data));
  }

  calHandle(i) {
    var data = this.students;
    this.average = Object.values(data).reduce(
      (avg, {
        values
      }, _, {
        length
      }) => avg + values / length,
      0
    );
  }
}
<table border="1">
  <tr>
    <th>Name</th>
    <th>Jan</th>
    <th>Feb</th>
    <th>March</th>
    <th>April</th>
    <th>action</th>
    <th>Average</th>
    <!-- </tr> -->
    <tbody *ngFor="let item of students; let i = index;">
      <tr>
        <td>{{item.name}}</td>
        <td>{{item.jan}}</td>
        <td>{{item.feb}}</td>
        <td>{{item.march}}</td>
        <td>{{item.April}}</td>
        <td><button (click)="calHandle(i)">calculate</button></td>
        <td>{{average}}</td>
      </tr>
    </tbody>

</table>

<!--
json data

[
 {"name": "josh", "jan":20,"feb":32, "march":"50", "April":45},
 {"name": "peter", "jan":20,"feb":32, "march":"50", "April":45},
 {"name": "gorge", "jan":20,"feb":32, "march":"50", "April":45}
]

-->

Above is my snippet for calculating the average of students on click event but whenever I am clicking on the button "calculate" the result I am getting is "NaN" so I am a little bit unsure that how do I provide only number value to prevent "NaN" error and what should I do for getting average of a particular student on button click.

2 Answers 2

2

Try like this:

.ts

calHandle(i: number) {
    var sum = 0;
    var keys = Object.keys(this.students[i]);
    keys.forEach(key => {
      if (key != "name") {
        sum += Number(this.students[i][key]);
      }
    });
    this.students[i].average = sum / (keys.length - 1);
}

.html

<table border="1">
  <tr>
    <th>Name</th>
    <th>Jan</th>
    <th>Feb</th>
    <th>March</th>
    <th>April</th>
    <th>action</th>
    <th>Average</th>
    </tr>
    <tbody *ngFor="let item of students; let i = index;">
      <tr>
        <td>{{item.name}}</td>
        <td>{{item.jan}}</td>
        <td>{{item.feb}}</td>
        <td>{{item.march}}</td>
        <td>{{item.April}}</td>
        <td><button (click)="calHandle(i)">calculate</button></td>
        <td>{{item.average}}</td>
      </tr>
    </tbody>
</table>

Working Demo

Sign up to request clarification or add additional context in comments.

1 Comment

Thank You, @Adrita Sharma, you made my day once again..!
0

You could use Object.entries to check the key of your object and omit it if it is 'name':

const result = [
 {"name": "josh", "jan":20,"feb":32, "march":"50", "April":45},
 {"name": "peter", "jan":20,"feb":32, "march":"50", "April":45},
 {"name": "gorge", "jan":20,"feb":32, "march":"50", "April":45}
].map(getAverage);

function getAverage(obj) {
  return Object.entries(obj).reduce((avg, obj, _, { length }) => obj[0] == 'name' ? avg : avg + obj[1] / length, 0);
}


console.log(result);

So in your case it would be:

calHandle(i) {
  var data = this.students;
  this.average = Object.entries(data).reduce(
    (avg, obj, _, {
      length
    }) => obj[0] == 'name' ? avg : avg + obj[1] / length,
    0
  );
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.