0
votes

I have service which returns data as expected when injected to a component. However when i subscribe to the service method and assign the response to a public variable upon initialization of the component. The variable remained to be undefined

here is my service

import {Injectable} from '@angular/core';
import { Observable }     from 'rxjs/Observable';
import { Headers, Http, RequestOptions, Response } from '@angular/http';

// Statics
import 'rxjs/add/observable/throw';

// Operators
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toArray';

@Injectable()
export class DataService {

  public errorMessage:string;

  private URL = 'MyUrl';  

  constructor(
    private http: Http
  ){}

  getData(token:string) :Observable<Response>
  {
      return this.http.get(this.URL + 'somedata?token='+token)
                 .map(response => response.json())
                 .catch(this.ThrowError);
  }


  private ThrowError (error: any) 
  {
    let errMsg = (error.message) ? error.message :
    error.status ? `${error.status} - ${error.statusText}` : 'Server error';
    console.error(errMsg); 
    return Observable.throw(errMsg);
  }

  private ExctractData(res:Response)
  {
    let body    = res.json();
    return body.data || {};
  }
}

And here is my component

import { Component, OnInit } from '@angular/core';


import { DataService } from '../data.service';
import 'rxjs/add/operator/map';


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



  public DataSet:any;

  public datasets:any;

  constructor(
    private DataService:DataService
  ) { }

  ngOnInit()
  {
    this.getData();
    this.datasets = this.DataSet;
    console.log(this.DataSet); //Why this returns undefined while it has been set in this.getData function?

  }


  getData()
  {

    this.DataService.getData(localStorage.getItem('token'))
                     .subscribe(
                        DataSet =>this.DataSet = DataSet,
                        error => console.error('Error: ' + <any>error),
                        () => console.log('Completed!')
                      )
  }

}

My problems is with ngOnInit() seems it can't initialize the Dataset to new values any ideas?

2

2 Answers

1
votes

You see 'undefined' in the console because of the async nature of Observable and subscribe. The console.log method gets executed before the callback function of subscribe. I hope it helps

0
votes

That's because this.getData() will call async method. So its completely unknown to it that by what time data will be returned. On other side, this.datasets = this.DataSet; will be executed immediately after execution of this.getData() (which calls async method) line. So, obviously this.Dataset is not filled up with data yet and so it is undefined.

What you can do is,

  ngOnInit()
  {
    this.getData();
  }


  getData()
  {
    // this is async call and its unknown that how long this process would take to fetch data.
    this.DataService.getData(localStorage.getItem('token'))
                     .subscribe(
                        DataSet =>{    
                           this.DataSet = DataSet;
                           console.log(this.DataSet)  //<<<<here it will print data to the console.
                        },
                        error => console.error('Error: ' + <any>error),
                        () => console.log('Completed!')
                      )
  }