4
votes

I am using observable in Angular2. As I know so far, each Observable instance come with an observer(1:1), and when we emit something with observer.next(value) we can get that value with observable.subscribe((value) => {}).

var observable = Observable.create(observer => {
  observer.next(value);
}
.map(value=>{})
.catch(...)
observable.subscribe(value => {
  console.log(value);
})

How can I emit value without knowing the corresponding observer, because I want to emit value outside create function. One possible solution is save observer into some global variable but I think an observable should be enough. Any suggestion for this ??

1
Perhaps you are looking for something like Subject? - cartant
Oh, It looks like this can be done using Subject instead of Observable, Thank you very much!! I will take time to look at it further. Or I think maybe I can create a class doing what I need :) - dttung1412
Subject is the way to go. Also note that it is not a 1:1, you can subscribe multiple times - Meir
Oh my mistake, I thought that every time we subscribe there's only one observer, but turn out that each subscribe create one different observer. Terrible misunderstanding ><!! - dttung1412
Indeed. Subject is the one you need to use. It is equivalent to q.defer() in angular 1. In your function you then return the subject, which is equ ivalent to defer.promise. Also defer.reject = subject.error(), subject.next= defer.resolve - hannes neukermans

1 Answers

7
votes

You're mixing multiple things together. Observables are not in 1:1 relation with Observers (more precisely it's 1:N). If you want to be able to manually emit values you need a Subject which acts as an Observable and an Observer at the same time. Practically this means you can call its next() method and it'll propage the value to all its subscribers (Observers).

For example consider the following code in TypeScript:

import {Subject} from 'rxjs';

let source = new Subject();

source.subscribe(val => console.log('Observer 1:', val));
source.subscribe(val => console.log('Observer 2:', val));

source.next(42);
source.next('test');

This will print to console:

Observer 1: 42
Observer 2: 42
Observer 1: test
Observer 2: test

See live demo: http://plnkr.co/edit/gWMFMnPlLJVDC1pQi8pH?p=preview

Read more:

Be aware that Observable.create() is a very different animal. It takes as a parameter a function that is called every time a new Observer subscribes. That's why it take the newly subscribed Observer as an argument. In this function you can for example call next() method on the Observer to send it some default value that all subscribes need to receive.

So you probably want to use Subject instead of Observable.create().