DuckFterminal
DuckFterminal

Reputation: 149

How to get data as instance of a class from API

I am a newbie Angular, currently I need to get data from an API, in EmployeesModels I have installed a calculation method. With raw data everything worked but data from API it had an error at the computeMonthlySalary method. I will show my code below, any help or suggestions. Thanks you very much!

EmployeesModels:

export class Employees implements IEmployees {
    constructor(public code: string, public name: string, public gender: string,
        public annualSalary: number, public dateOfBirth: string) {
    }
    computeMonthlySalary(annualSalary: number): number {
        return this.annualSalary / 12;
    }
}

Services

import {Employees} from '../Models/Employees';
import {HttpClient} from '@angular/common/http'
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})

export class EmployeeServicesService {
  constructor(private _http: HttpClient) { }
  getEmployees(): Observable<Employees[]> {
    return this._http.get<Employees[]>('http://localhost:55416/api/employees');
  }    
}

EmployeeComponent

export class EmployeeComponent implements OnInit { 
    constructor(private readonly _employeeService: EmployeeServicesService){}
    employees: Employees[] = [];
    ngOnInit(){
        this._employeeService.getEmployees()
        .subscribe(employeesData => this.employees = employeesData);
    }
    
}

employeeList.component.template.html

<table>
    <thead>
        <tr>
            <th>Code</th>
            <th>Name</th>
            <th>Gender</th>
            <th>Annual Salary</th>
            <th>Date of Birth</th>
            <th>Monthly Salary</th>
        </tr>
    </thead>
    <tbody>
        <ng-container *ngFor="let employee of employees;">
        <tr>
            <td>{{employee.code | uppercase}}</td>
            <td>{{employee.name |custompipe: employee.gender}}</td>
            <td>{{employee.gender}}</td>
            <td>{{employee.annualSalary| currency:'USD':true:'1.3-3'}}</td>
            <td>{{employee.dateOfBirth}}</td>
            <td>{{employee.computeMonthlySalary()|currency:'USD':true:'1.3-3'}}</td>
        </tr>
    </ng-container>
        <tr *ngIf="!employees || employees.length==0">
            <td colspan="6">
                No employees to display
            </td>
        </tr>
    </tbody>
</table>

And this error when I'm trying display computeMonthlySalary result

core.js:4197 ERROR TypeError: employee_r2.computeMonthlySalary is not a function

Upvotes: 0

Views: 191

Answers (1)

h0ss
h0ss

Reputation: 643

this._http.get<Employees[]>('http://localhost:55416/api/employees')

Angular HTTP service will not instantiate a new class for you, it will only give you the response typed as the type parameter you provided, this might be confusing, but essentially you are not given instances of Employees back by HttpClient it merely helps with typings.

To achieve what you need, you have to create the instance yourself, I suggest you do the following

getEmployees(): Observable<Employees[]> {
  return this._http.get<IEmployees[]>('http://localhost:55416/api/employees').pipe(
    map((employees) => {
      return employees.map((employee) => {
         // Instantiate your classes
         return new Employee(employee.code, ....)
      });
    }),
  );
} 

Or you can use something like https://github.com/typestack/class-transformer

Upvotes: 1

Related Questions