Home > Enterprise >  Angular Binding bind empty data
Angular Binding bind empty data

Time:07-07

I am new to Angular and type script. I am facing a problem when I call the Get API to show the employees the *ngFor iterate correctly as the count of the returned array but the bonded data is not empty as shown!!

the output image

when I print the data on the console this is the JSON that gets

Array(8)
0: {employeeID: 1, employeeName: 'Taha BABI', employeeSalary: 400000, intendedDate: '2022-07-02T19:15:39.68'}
1: {employeeID: 2, employeeName: 'Aya', employeeSalary: 5000000, intendedDate: '2022-01-06T00:00:00'}
2: {employeeID: 4, employeeName: 'Rami', employeeSalary: 1000000, intendedDate: '2022-07-02T19:16:27.095'}
3: {employeeID: 5, employeeName: 'Rami', employeeSalary: 1000000, intendedDate: '2022-07-02T19:16:27.095'}
4: {employeeID: 6, employeeName: 'Rami', employeeSalary: 1000000, intendedDate: '2022-07-02T19:16:27.095'}
5: {employeeID: 7, employeeName: 'Rami', employeeSalary: 1000000, intendedDate: '2022-07-02T19:16:27.095'}
6: {employeeID: 8, employeeName: 'Ahmad BABI', employeeSalary: 1000000, intendedDate: '2022-07-04T00:00:00'}
7: {employeeID: 9, employeeName: 'Adnan', employeeSalary: 500000, intendedDate: '2022-01-01T00:00:00'}
length: 8
[[Prototype]]: Array(0)

this is the Employee Module

export class Employee
{
  public EmployeeID: number;
  public EmployeeName: string;
  public EmployeeSalary: number;
  public IntendedDate: Date;
}

this is the service class

import { Injectable } from "@angular/core"
import { Employee } from "./Employee.Module"
import { HttpClient } from "@angular/common/http"

@Injectable({
  providedIn: 'root'
})

export class EmployeeService
{
  constructor(private http:HttpClient) { }
  employeeFormData: Employee = new Employee();
  public employeesList: Employee[];
  readonly url = "https://localhost:7075/api/employee";
  PostEmployeeData()
  {
    return this.http.post(this.url, this.employeeFormData  "/insert")
  }

  RefreshEmployeesList()
  {
    this.http.get(this.url).toPromise().then(res => {
      this.employeesList = res as Employee[];
      console.log(this.employeesList);
    });

  }
}

this is the employee.component.ts

import { Component, OnInit } from "@angular/core"
import { EmployeeService } from "../Shared/EmployeeService";
@Component({
  selector: "Employee",
  templateUrl: "./Employee.Component.html",
  styleUrls: [

  ]
})
export class EmployeeComponent
{
  constructor(public service: EmployeeService) { }

  ngOnInit()
  {
    //console.log(this.service.employeesList);
    this.service.RefreshEmployeesList();
    console.log("init");

  }
}

this is the employee.component.html

<div >
  <h1>Employees CRUD</h1>
</div>
<div >
  <div >
    <EmployeeForm>
      Please Wait Form....
    </EmployeeForm>
  </div>
  <div >
    <table >
      <thead >
        <tr>
          <th>Employee Number</th>
          <th>Employee Name</th>
          <th>Employee Salary</th>
          <th>Employee Intended Date</th>
          <th></th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="let employee of service.employeesList;">
          <td>{{employee.EmployeeID}}</td>
          <td>{{employee.EmployeeName}}</td>
          <td>{{employee.EmployeeSalary}}</td>
          <td>{{employee.IntendedDate}}</td>
          <td></td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

CodePudding user response:

Didn't go to deep into your code but I see a few problems...

on your EmployeeComponent template, instead of iterating from the service itself, you should create a property and fill it upon initialization.

    export class EmployeeComponent {
    
        private subscription;

        public employeeList = [];

        constructor(public service: EmployeeService) { }

        ngOnInit(){
            this.subscription = this.service.RefreshEmployeesList()
                                  .subscribe(list => {
                                     this.employeeList = list;
                                   });
        }

        ngOnDestroy(){
           this.subscription.unsubscribe();
        }
    }

Then in you service instead of having the list there, you can just return it.

Also instead of converting to a promise, which in my opinion is really not required, you can just subscribe to the observable on the component itself and handle your logic there.

/// EmployeeService


  RefreshEmployeesList()
  {
    return this.http.get(this.url);
  }

then in the template you can just reference the list from the component itself...


       <tr *ngFor="let employee of employeesList;">
          <td>{{employee.EmployeeID}}</td>
          <td>{{employee.EmployeeName}}</td>
          <td>{{employee.EmployeeSalary}}</td>
          <td>{{employee.IntendedDate}}</td>
          <td></td>
        </tr>

CodePudding user response:

Something like this:

Service:

Dont' use .toPromise()

RefreshEmployeesList(): Observable<Employee[]> {
    return this.http.get(this.url);
}

Component:

export class EmployeeComponent {
  employees$: Observable<Employee[]>;

  constructor(private service: EmployeeService) { }

  ngOnInit(): void {
    this.employees$ = this.service.RefreshEmployeesList();
  }
}

HTML:

| async automatically unsubscribes

...
<tr *ngFor="let employee of employees$ | async">
...
  • Related