0

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;
  }
}
Calvin
  • 347
  • 1
  • 4
  • 18

1 Answers1

2

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.

Teddy Sterne
  • 13,774
  • 2
  • 46
  • 51