1
const ex = ajax.getJSON('https://httpbin.org/get?a=24');
ex.pipe(pluck('args')).subscribe(x => console.log('Args: ', x));
ex.pipe(pluck('headers')).subscribe(x => console.log('Headers: ', x));

Code above(StackBlitz) initiates two ajax requests by one for each subscription.

What is correct way to initiate only one observable pipe/chain for all existing subscriptions?

I can achieve that with introduce a Promise for ajax(StackBlitz):

const p = new Promise(resolve => {
  ajax.getJSON('https://httpbin.org/get?a=24')
  .subscribe(res => resolve(res));
});

from(p).pipe(pluck('args')).subscribe(x => console.log('Args: ', x));
from(p).pipe(pluck('headers')).subscribe(x => console.log('Headers: ', x));

But I believe there must be some more convienient way.

vp_arth
  • 14,461
  • 4
  • 37
  • 66

2 Answers2

4

shareReplay from comments solves my issue:

const src = tag => of(42)
  .pipe(tap(_ => console.info(tag, 'source called')));

const ex = src('shareReplay').pipe(
  shareReplay(1)
);

ex.subscribe(x => console.log('sa:', x));
ex.subscribe(x => console.log('sb:', x));
shareReplay source called
sa: 42
sb: 42

Full demo

vp_arth
  • 14,461
  • 4
  • 37
  • 66
2

You can use the publish operator for that:

const ex = ajax.getJSON('https://httpbin.org/get?a=24').pipe(publish());
ex.pipe(pluck('args')).subscribe(x => console.log('Args: ', x));
ex.pipe(pluck('headers')).subscribe(x => console.log('Headers: ', x));
ex.connect();

The ajax request will take place just once, and only after the connect() method is called (stackblitz demo).

julianobrasil
  • 8,954
  • 2
  • 33
  • 55
  • Can't result be received, when subscription was done after connect? – vp_arth Jul 11 '19 at 14:35
  • 1
    Oh, I think you're getting the two parts (args and headers) in different places of the code, uh? In that case, imo, maybe you should create an additional `ReplaySubject` just to reemit the last grabbed result from the backend. But I'll do a little research and come back if I have good news. – julianobrasil Jul 11 '19 at 14:50
  • Significant part of my issue - I should be able to subscribe for it before and after actual data received. First subscribe should initiate data fetching, others waiting for it or receive it immediately, if already fetched. I add with Promise implementation to my question for clarity. May be `shareReplay` advice from comments will be useful, I read it now. – vp_arth Jul 11 '19 at 14:58