0

Im trying to make a api service and assign the data to a variable, but, the variable is not updating, and getting as undefined when I try to log after API service.

import {Component,Input,Output,EventEmitter} from 'angular2/core';
import {NgClass,NgFor} from 'angular2/common';
import {Observable} from 'rxjs/Observable';
import {ChangeDetectionStrategy} from 'angular2/core';
import {ValuesPipe} from '../pipes/values';
import {ApiRequestService, Query} from '../services/apiRequestService';




@Component({
selector: 'browsePCLatestRelease',  // <home></home>
directives: [NgClass,NgFor],
changeDetection: ChangeDetectionStrategy.OnPush,
pipes: [ ValuesPipe ],
styles: [ require('./browsePCLatestRelease.less') ],
template: require('./browsePCLatestRelease.html')
})
export class browsePCLatestRelease {

public arrayOfKeys;
pcLatestrelease:Array<any> ;
query: Query;

constructor(private _apiService: ApiRequestService) {
}

ngOnInit() {

this.query = this._apiService.createQuery('browsePC.getIssue');
this.query.params({
  volume: '60',
  issue: '50'
});
this._apiService.execute(this.query)
  .subscribe(

    data => this.pcLatestrelease=data,
    error => console.log(error),
    () => console.log('pcLatestrelease retrived')

  );

console.log('this.pcLatestrelease');
console.log(this.pcLatestrelease);  // logged as undefined

}


}

HTML

<div *ngFor = "#thisRelease of pcLatestrelease">
        {{thisRelease.title}}
</div>

Can someone help me, Thanks in advance.

nikhil reddy
  • 96
  • 1
  • 9

1 Answers1

1

The code is not executed line-by-line as listed in your function

export class browsePCLatestRelease {

  ...

  ngOnInit() {

    this.query = this._apiService.createQuery('browsePC.getIssue');
    this.query.params({
      volume: '60',
      issue: '50'
    });
    this._apiService.execute(this.query)
    .subscribe(
  // here you pass a function to subscribe of an observable
  // the function gets called when the data arrives (from the server)
      data => this.pcLatestrelease=data,
      error => console.log(error),
      () => console.log('pcLatestrelease retrived')
    );

  // this code is executed immediately after the function (callback) 
  // was passed to subscribe, but the function wasn't yet executed
    console.log('this.pcLatestrelease');
    console.log(this.pcLatestrelease);  // logged as undefined
  }
}

when then the data arrives eventually

data => this.pcLatestrelease=data,

is executed and the value assigned to this.pcLatestrelease

If you want your code to be executed after the data arrived use

export class browsePCLatestRelease {

  ...

  ngOnInit() {

    this.query = this._apiService.createQuery('browsePC.getIssue');
    this.query.params({
      volume: '60',
      issue: '50'
    });
    this._apiService.execute(this.query)
    .subscribe(
  // here you pass a function to subscribe of an observable
  // the function gets called when the data arrives (from the server)
      data => {
         this.pcLatestrelease=data;
         console.log('this.pcLatestrelease');
         console.log(this.pcLatestrelease);  // logged as undefined
      },
      error => console.log(error),
      () => console.log('pcLatestrelease retrived')
    );

  }
}

update

import {Component,Input,Output,EventEmitter, NgZone} from 'angular2/core';

...

export class browsePCLatestRelease {

  constructor(private _apiService: ApiRequestService, private _zone.NgZone) {
  }    

  ...

  ngOnInit() {

    this.query = this._apiService.createQuery('browsePC.getIssue');
    this.query.params({
      volume: '60',
      issue: '50'
    });
    this._apiService.execute(this.query)
    .subscribe(
  // here you pass a function to subscribe of an observable
  // the function gets called when the data arrives (from the server)
      data => {
         this.zone.run(() => {
           this.pcLatestrelease=data;
           console.log('this.pcLatestrelease');
           console.log(this.pcLatestrelease);  // logged as undefined
         });
      },
      error => console.log(error),
      () => console.log('pcLatestrelease retrived')
    );

  }
}
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Thanks, this is working fine,but I want to use this variable in HTML, – nikhil reddy Apr 25 '16 at 15:25
  • That shouldn't be a problem. Angular might throw if you bind like `pcLatestrelease.someProperty`. You can fix this using the Elvis operator like `pcLatestrelease?.someProperty` then Angular doesn't try to access `.someProperty` until `pcLatestrelease` has a value. – Günter Zöchbauer Apr 25 '16 at 15:28
  • updated with HTML, the variable is not updating in HTML and reflecting with the new data. – nikhil reddy Apr 25 '16 at 15:30
  • I updated my answer. I'm not 100% sure if this fixes your issue but it's likely. This seems to be caused by your ApiRequestService which seems to leave Angulars zone. I would need more details about this service to diagnose the problem. Please try my proposed workaround first. – Günter Zöchbauer Apr 25 '16 at 15:33