Manube
Manube

Reputation: 5242

how to implement rxjs subscription in angular 2?

I have a service with following code:

import {Injectable} from 'angular2/core';
import {Observable} from 'rxjs/Observable';
import {Observer} from 'rxjs/Observer';
import 'rxjs/add/operator/share';
import {Article} from './article';

@Injectable()
export class ArticleService {
public articleSelected$: Observable<Article>;
private _observer: Observer<Article>;

constructor() {
this.articleSelected$ = new Observable(observer =>
    this._observer = observer).share();
}
selectArticle(article:Article){
this._observer.next(article);
}}

and in my component:

export class seeArticle{

subscription: any;

constructor(private _articleService: ArticleService) {
}
ngOnInit() {
    this.subscription = this._articleService.articleSelected$
        .subscribe(article => this.onArticleSelected(article));
}
onArticleSelected(article){
    console.log("an article was selected",article);
}
}

When I select an article (by clicking on it) in another component, the selectArticle service function gets executed, no problem there. However, this._observer.next(article); seems to trigger the following error:

"TypeError: Cannot read property 'next' of undefined"

Being very new to angular 2 and Rxjs, I cannot figure it out

Upvotes: 2

Views: 3355

Answers (1)

dfsq
dfsq

Reputation: 193261

The problem with your code is that this._observer is not yet available when selectArticle method is invoked, because

observer => this._observer = observer

part is asynchronous.

So instead of creating Observable manually, use EventEmitter that wraps Observable properly for you:

@Injectable()
export class ArticleService {
  public articleSelected$: EventEmitter<Article>;

  constructor() {
    this.articleSelected$ = new EventEmitter();
  }

  selectArticle(article:Article){
    this.articleSelected$.next(article);
  }

}

Demo: http://plnkr.co/edit/sz5Dzm1SoisTJlvj8RcQ?p=info

Upvotes: 1

Related Questions