dafyddPrys
dafyddPrys

Reputation: 928

Angular2 Observables - Creating my own - subscriber undefined

I can't quite tell if this is a scoping issue or an issue with how I've set up my observables, but maybe you can help.

Firstly, my logic. My overall aim is to be able to check if some data is held locally before sending off a http.get request for it. What I'd like to do is return the locally held data back if it exists, and I thought that I could make this return an observable so that I could subscribe to the output of this function regardless of if it returned local data or remote data. Any thoughts on this logic would be appreciated!

I am following this blog post by Cory Rylan to implement my own observable. I am running into a problem where I cannot get my Observer to be defined in my getData function.

Here is Cory's working demo

Here is my not-working demo - You can see in the log that this._dataObserver in the service is undefined, whereas in Cory's it is. This is what is causing me issues.

Here are snippets from the code:

App.ts

@Component({
  selector: 'my-app',
  template: `
    <landing-page></landing-page>    
  `,
  providers: [DataService],
  directives: [LandingPageComponent]
})
export class App {
  constructor() { }
}

bootstrap(App, [HTTP_BINDINGS])
  .catch(err => console.error(err));

LandingPageComponent.ts

@Component({
  selector: 'landing-page',
  template : `
    hello
  `,
})
export class LandingPageComponent implements OnInit{
  data : Observable<any[]>;
  constructor(
    private _dataService : DataService
  ) { }

  ngOnInit() {
    this.data = this._dataService.data$;
    this._dataService.getData();
  }
}

DataService

@Injectable()
export class DataService {

   data$ : Observable<any[]>; // data stream
   private _baseUrl: string;
   private _dataObserver : Observer<any[]>;
   private _dataStore : {
    data : any[]
   };

  constructor (
    private _http: Http
  ) {
    this._baseUrl  = 'http://56e05c3213da80110013eba3.mockapi.io/api';
    this.data$ =  new Observable(observer => this._todosObserver = observer).share();
    this._dataStore = { data: [] };
  }

  /** **************
  * Public functions
  *****************/

  getData () {
    this._http.get(`${this._baseUrl}/todos`)
      .map(data => data.json())
      .subscribe( data => {
      this._dataStore.data = data;
      console.log(this._dataObserver);   //<------ This is undefined for me!
      this._dataObserver.next(this.data);
    },
    error => {
      console.log('couldn\'t load data! ' + error );
    });

  }

}

Thank you for any thoughts

Upvotes: 3

Views: 713

Answers (1)

Thierry Templier
Thierry Templier

Reputation: 202316

_dataObserver is null because you don't subscribe on the associated observable. Don't forget that observables are lazy...

You could try the following:

ngOnInit() {
  this.data = this._dataService.data$.subscribe(data => { // <-----
    console.log(data);
  });
  this._dataService.getData();
}

Edit

In addition, there is a typo in your code:

this.data$ =  new Observable(observer => this._todosObserver = observer).share();

You should use _dataObserver instead of _todosObserver:

this.data$ =  new Observable(observer => this._dataObserver = observer).share();

Upvotes: 3

Related Questions