Calvin
Calvin

Reputation: 377

Typescript 'this' scope issue

When I call the findFromList function from a component, this error gets triggered:

ERROR TypeError: Cannot read property 'searchInArray' of undefined at push../src/app/shared/services/filter.service.ts.FilterService.searchInObject (filter.service.ts:40)

This seems to be because 'this' doesn't refer to FilterService anymore in the searchInObject function.

Angular FilterService code:

import {Injectable, EventEmitter} from '@angular/core';

@Injectable()
export class FilterService {


  findFromList(list, keyword) {
    return list.filter((el) => this.search(el, keyword));
  }

  search(el, keyword) {
    const type = Array.isArray(el) ? 'array' : typeof el;
    const searchFunc = this.getFuncByType(type);

    return searchFunc(el, keyword);
  }

  getFuncByType(type) {

    const match = {
      'string': this.searchInText,
      'number': this.searchInText,
      'boolean': this.searchInText,
      'array': this.searchInArray,
      'object': this.searchInObject,
    };

    if (typeof match[type] !== 'undefined') {
      return match[type];
    } else {
      throw new Error(`Unknown element type "${type}"`);
    }
  }

  searchInText(text, keyword) {
    return (text.toString().indexOf(keyword) !== -1);
  }

  searchInObject(obj, keyword) {
    return this.searchInArray(Object.values(obj), keyword);
  }

  searchInArray(arr, keyword) {
    return arr.find((el) => this.search(el, keyword)) !== undefined;
  }
}

Upvotes: 0

Views: 284

Answers (1)

Teddy Sterne
Teddy Sterne

Reputation: 14219

It is be cause of the object you define in getFuncByType. It causes the this to refer to that object and not the FilterService class. Update the definition to be:

const match = {
  'string': this.searchInText.bind(this),
  'number': this.searchInText.bind(this),
  'boolean': this.searchInText.bind(this),
  'array': this.searchInArray.bind(this),
  'object': this.searchInObject.bind(this),
};

By binding each function to this it will keep the context of the function as the class' context.

Upvotes: 2

Related Questions