Yogi Bear
Yogi Bear

Reputation: 963

Angular class variable referenced inside subscribe result is undefined

listConstituents is DECLARED in the class, and INITIALIZED in ngOnInit. getConstituents function's first line is a call to getChildren (which places an http request).

Inside the subscribe, the returned 'data' is fine, but listConstituents is undefined and is never set:

export class ...
constructor() {}

  listConstituents: Constituent[];

  ngOnInit(): void {
    // debugger shows this next line is correct:  Array(0) []
    this.listConstituents = new Array<Constituent>();
  }

  getConstituents() {
      this.dataService.getChildren(this.ProdID, 'Constituent').subscribe(
        data => {   **<-- return array of any**
          for (let i = 0; i < data.length; i++) {
             let x = <Constituent>data[i];  <-- x cast to Constituent
             if ( x.Active ) {  <-- correctly accesses this part of Constituent
                this.listConstituents.push(x);   <-- ***this.listConstituents is undefined !***
              }
          }
        }
      etc.

Upvotes: 2

Views: 652

Answers (3)

Ankur Chauhan
Ankur Chauhan

Reputation: 100

This is because your this is referred to get Children function. Assigning this reference to self and using self to access listConstituent of parent class can help.

getConstituents() { 
    let self = this;
    this.dataService.getChildren(this.ProdID, 'Constituent')
                    .subscribe( data => { **<-- return array of any** for (let i = 0; i < data.length; i++) { let x = <Constituent>data[i]; <-- x cast to Constituent if ( x.Active ) { <-- correctly accesses this part of Constituent self.listConstituents.push(x); <-- ***this.listConstituents is undefined !*** } } 
}

Upvotes: 0

XXIV
XXIV

Reputation: 358

I would recommend what Karthik recommended (just instantiating it when you declare it).

Since you're using anonymous functions and concise methods, your this should be correct (I don't agree with what Ankur suggested)

I also wanted to give another way of how you're pushing the items onto the array:

this.dataService.getChildren(this.ProdID, 'Constituent').subscribe(
    (data: Array<Constituent>) => {
      this.listConstituents.push(...data.filter(x => x.Active));
    }

Upvotes: 0

Karthik
Karthik

Reputation: 21

I guess getConstituents() gets called before onInit or otherwise executes before onInit somehow.

Declare member variable like this.

listConstituents: Constituent[] = new Array<Constituent>();

Upvotes: 1

Related Questions