r3plica
r3plica

Reputation: 13387

Angular4 Cannot read property 'list' of undefined

I have this component which passes a method to another component. It was doing it like this:

constructor(
  public categoryData: CategoryDataService
) {
}

And the html to pass the method looked like this:

[list]="categoryData.list"

This was working fine, as long as the list method had no parameters. Now I have a method that does have parameters, but I can get the parameters from the component, so I created a wrapper method like this:

listCriteria() {
  this.criteriaData.list(this.category.id);
} 

But, when I add this html:

[list]="listCriteria"

gives me an error:

ERROR TypeError: Cannot read property 'list' of undefined

Just for reference, this is what the service looks like:

import { Injectable } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http/src/response';
import { environment } from '../../environments/environment';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';

import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

import { ICriteria } from './interfaces/criteria.shared';

const API_URL = environment.apiUrl;
const API_Path = '/criteria';

@Injectable()
export class CriteriaDataService {
  constructor(private _http: HttpClient) { }

  public list = (categoryId: string, includes?: string): Observable<ICriteria[]> => {
    return this._http
      .get<ICriteria[]>(API_URL + API_Path, { params: { categoryId: categoryId, includes: includes || '' } })
      .catch(this.handleError);
  }

  private handleError(error: HttpErrorResponse) {
    return Observable.throw(error);
  }
}

Upvotes: 1

Views: 465

Answers (1)

yurzui
yurzui

Reputation: 214175

A function's this keyword behaves a little differently in JavaScript.

The value of this is determined by how a function is called.

When you pass function to other component you need to ensure that it will be called with correct context.

The simple way of doing this is just use the same method you used in your service: instance arrow function

listCriteria = () => this.criteriaData.list(this.category.id);

This way this will refer to correct component instance.

Upvotes: 1

Related Questions