Joshua Kemmerer
Joshua Kemmerer

Reputation: 1673

Why is a property on my Typescript-defined class showing up as undefined?

I have a property options, that I define in my component class, but it's showing up as undefined when I run the code in the browser. I can't find anything logically wrong with the code, but figure this may be some sort of bug or versioning issue.

Here is the component class:

import { Component, OnInit, Input } from '@angular/core';
import { FormControl } from '@angular/forms';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/operator/map';

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

  myControl = new FormControl();
  selectedOption: any;
  filteredOptions: Observable<any[]>;

  @Input() optionTitle: string;
  options: [
    {
      name: 'something'
    },
    {
      name: 'something else'
    }
  ];

  constructor() {
  }

  ngOnInit() {
    this.filteredOptions = this.myControl.valueChanges
        .startWith(null)
        .map(item => item && typeof item === 'object' ? item.name : item)
        // this is where it's saying this.options is undefined.
        // (if I do console.log(this.optionTitle), that shows up perfectly fine)
        .map(name => name ? this.filter(name) : this.options.slice());
  }

  filter(input: string): any[] {
    return this.options.filter(option =>
      option.name.toLowerCase().indexOf(input.toLowerCase()) === 0);
  }

  displayFn(option: any): string | any {
    return option ? option.name : option;
  }

  select($event): void {
    this.selectedOption = $event.option.value;
  }
}

Here is the error I'm getting in the browser:

SelectorComponent.html:3 ERROR TypeError: Cannot read property 'slice' of undefined
    at MapSubscriber.project (selector.component.ts:35)
    at MapSubscriber.webpackJsonp.../../../../rxjs/operator/map.js.MapSubscriber._next (map.js:77)
    at MapSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
    at MapSubscriber.webpackJsonp.../../../../rxjs/operator/map.js.MapSubscriber._next (map.js:83)
    at MapSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
    at MergeAllSubscriber.webpackJsonp.../../../../rxjs/OuterSubscriber.js.OuterSubscriber.notifyNext (OuterSubscriber.js:19)
    at InnerSubscriber.webpackJsonp.../../../../rxjs/InnerSubscriber.js.InnerSubscriber._next (InnerSubscriber.js:23)
    at InnerSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
    at Object.subscribeToResult (subscribeToResult.js:17)
    at MergeAllSubscriber.webpackJsonp.../../../../rxjs/operator/mergeAll.js.MergeAllSubscriber._next (mergeAll.js:85)

What could possibly be going wrong here?

Upvotes: 0

Views: 253

Answers (2)

Retsam
Retsam

Reputation: 33389

You're never initializing option to anything, you've got this:

options: [
  {
    name: 'something'
  },
  {
    name: 'something else'
  }
];

but what I think you want is

options = [
  {
    name: 'something'
  },
  {
    name: 'something else'
  }
];

The second initializes the field, while the first one is just a type definition, (roughly equivalent to options: Array<{name: 'something' | 'something else'}>)

Upvotes: 2

Michael Beeson
Michael Beeson

Reputation: 2875

From looking at your code, I suspect you need to replace

options:

with

options =

Upvotes: 2

Related Questions