Jules
Jules

Reputation: 15199

Multicast observable: attempting to subscribe results in "cannot read property 'subscribe' of undefined" error

I have a need in my code to perform an AJAX request and send the resulting data to two different places, so I figured using a multicast observable was the easiest way of achieving this. My code looks like this:

In the constructor for my 'app' object:

this.getEpisodeDescription = (id) => jsonLoader("http://www.randomtext.me/api/lorem/p-2/8-24", "text_out");

function jsonLoader (url, field)
{
    let stream = Rx.Observable.ajax ({ url: url, crossDomain: true })
                                .retry (1)
                                .pluck ("response");
    if (field !== undefined)
        return stream.pluck(field);
    else
        return stream;
}

I've successfully used this method before to retrieve data for a single receiver, so I'm sure this is working OK. The caller is new, however:

loadSummary (id)
{
    let cachedValue = this.summaries.get(id);
    if (cachedValue !== undefined) return Rx.Observable.of(cachedValue);

    let observable = this.app.getEpisodeDescription(id);
    let multicast = observable.multicast ().refCount ();
    multicast.subscribe(result => this.summaries.put(id, result));
    return multicast;
}

When I try executing this method, I get the following stack trace:

Uncaught TypeError: Cannot read property 'subscribe' of undefined
    at Observable.ConnectableObservable._subscribe (app.js:44193)
    at Observable._trySubscribe (app.js:10253)
    at Observable.subscribe (app.js:10241)
    at RefCountOperator.call (app.js:44275)
    at Observable.subscribe (app.js:10238)
    at AsyncAction.SubscribeOnObservable.dispatch (app.js:71532)
    at AsyncAction._execute (app.js:21083)
    at AsyncAction.execute (app.js:21058)
    at AsyncScheduler.flush (app.js:21156)

(Ignore file name and line numbers -- I'm using webpack and it doesn't seem to be producing a working line number map at the moment)

Any ideas what's going on? Specifically, how does it happen that I get an object out of the call to multicast that has appropriate subscribe etc methods, but when you try to subscribe to it it apparently can't subscribe to the parent?

Upvotes: 0

Views: 218

Answers (1)

martin
martin

Reputation: 96891

The first parameter to the multicast() operator is either Subject factory function or a Subject instance.

This means you should be using it like this if you want to have one shared Subject instance:

let multicast = observable.multicast(new Subject()).refCount();

... or like this to make a new Subject for every observer:

let multicast = observable.multicast(() => new Subject()).refCount();

Upvotes: 1

Related Questions