1

I have a problem like this. I am developing a simple angular app. I am retrieving data from the database. For that, I have created a service.ts file like this.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';

import { Employee } from './employee';

@Injectable()
export class EmployeeService {
  selectedEmployee: Employee;
  public  employees: Employee[];
  readonly baseURL = 'http://localhost:3000/employees';

  constructor(private http: HttpClient) { }

  postEmployee(employee: Employee) {
    return this.http.post(this.baseURL, employee);
  }

  getEmployeeList() {
    return this.http.get(this.baseURL);
  }

}

And in the components file, I have coded like this to call this function in the service.ts file.

import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';

import { EmployeeService } from '../shared/employee.service';
import { Employee } from '../shared/employee';

declare var M: any;

@Component({
  selector: 'app-employee',
  templateUrl: './employee.component.html',
  styleUrls: ['./employee.component.css'],
  providers: [EmployeeService]
})
export class EmployeeComponent implements OnInit {

  constructor(private employeeService: EmployeeService) { }

  ngOnInit() {
    this.resetForm();
    this.refreshEmployeeList();
  }

  refreshEmployeeList() {
    this.employeeService.getEmployeeList().subscribe(function (res) {
      this.employeeService.employees = res as Employee[];
    });
  }

  resetForm(form?: NgForm) {
    if (form) {
      form.reset();
      this.employeeService.selectedEmployee = {
        _id: '',
        name: '',
        position: '',
        office: '',
        salary: null
      };
    }
  }

  onSubmit(form: NgForm) {
    if (form.value._id === '') {
      this.employeeService.postEmployee(form.value).subscribe((res) => {
        this.resetForm(form);
        M.toast({ html: 'Saved successfully', classes: 'rounded' });
      });
    }
  }
}

If I replace

this.employeeService.employees = res as Employee[];

This as

console.log(res);

It prints the all the data in the database correctly in the console window but with this.employeeService.employees = res as Employee[] line it is giving me an error like this.

core.js:1449 ERROR TypeError: Cannot set property 'employees' of undefined at SafeSubscriber.eval [as _next] (employee.component.ts:26) at SafeSubscriber.__tryOrUnsub (Subscriber.js:243) at SafeSubscriber.next (Subscriber.js:190) at Subscriber._next (Subscriber.js:131) at Subscriber.next (Subscriber.js:95) at MapSubscriber._next (map.js:85) at MapSubscriber.Subscriber.next (Subscriber.js:95) at FilterSubscriber._next (filter.js:90) at FilterSubscriber.Subscriber.next (Subscriber.js:95) at MergeMapSubscriber.notifyNext (mergeMap.js:151)

This is my HTML file.

<div class="row">
  <div class="col s12 m6">
    <div class="card blue-grey darken-1">
      <div class="card-content white-text">
        <div class="row">
          <div class="col s5">

          </div>
          <div class="col s7">
            <table class="responsive-table highLight">
              <thead>
                <tr>
                  <th>Name</th>
                  <th>Position</th>
                  <th>Office</th>
                </tr>
              </thead>
              <tr *ngFor="let emp of employees">
                <td>{{emp.name}}</td>
                <td>{{emp.position}}</td>
                <td>{{emp.office}}</td>
              </tr>
            </table>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

So what is the problem with my code?. Can someone help me to solve this problem?. I Look some examples, questions, and answers. They were not enough me to solve this problem. Thank You

1
  • make the changes suggested by @cgTag and use ngFor = let emp of employeeService.employees in your Template Commented Jun 1, 2018 at 3:33

3 Answers 3

3

Remove the word function and use (res) =>

this.employeeService.getEmployeeList().subscribe((res) => {
  this.employeeService.employees = res as Employee[];
});

The this was not the current component.

When working with TypeScript it's better to use the () => instead of function () because the fat arrow persists the current reference to this

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

Comments

0

Creat new variable in the component.

employees : any;

refreshEmployeeList() { 
this.employeeService.getEmployeeList().subscribe(function (res) { 
this.employees = res;

});

 }

Then use employees in the html file

6 Comments

Thank you. It works. But nothing is showing in the view. how can I change my HTML file to get it done? I have updated the view file now in the question.
Use object.key method and push data into employees and make final array of data then return employees. Object.keys(res).forEach(function(key) { this.employees.push(res[key]) }); return this.employees; Use above code in the refreshEmployeeList method.
Use object.keys method and make final array employees and return that array. Object.keys(res).forEach(function(key) { this.employees.push(res[key]); }); Return this.employees; Use this code in the refreshEmployeeList method.
this.employeeService.getEmployeeList().subscribe(function (res) { Object.keys(res).forEach(function(key) { this.employees.push(res[key]); }) return this.employees ; });
I put like this. But it is giving me the previous error again
|
0

Its because you are looping over employees in your html but there is no variable with name employees on the component class

You can say ngFor = let emp of employeeService.employees

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.