Search code examples
javascriptajaxeventsrxjsreactive-extensions-js

RxJS sending multiple unique ajax requests on event


If I have an event type; say a click event. That I want to fire 3 unique ajax requests for but I want to subscribe to the final result of all 3 requests

What is the proper design pattern for this sequence.

My current code block looks something like this

$rootScope.$eventToObservable('selectUser')
    .throttle(500)
    .map(data => {
        return angular.copy(data.additionalArguments[0].entity);
    })
    .select(d => {
        return {
            Member: MemberService.getMember(d.ID),
            otherData: MemberService.dataOtherData(d.ID),
            Notes: MemberService.getNotes(d.ID),
            Log: MemberService.getLog(d.ID)
        }
    })
    .switchLatest() //Code current dies here with an object is not a function error. I believe because the return object is not an obserable. But not sure what the proper design pattern is.
    .subscribe(model => {
        //I would like that model would contain an object with the result of the 3 responses above.
        $scope.model = model;
});

Solution

  • You can use zip to synchronize your requests. zip will cause all observables to be subscribed, and yield each time all of those observables fire. So, once the nth item from each observable is yielded, zip will yield it's nth value, which is created by using the nth values from the original observables.

    Once you have that, can you use switchLatest, which works on Observable<Observable<T>>, and makes sure it's always subscribed to the latest observable. So, if you select a new user, it'll just unsubscribe from any pending request, and subscribe to the next one instead.

    $rootScope.$eventToObservable('selectUser')
        .throttle(500)
        .map(data => {
            return angular.copy(data.additionalArguments[0].entity);
        })
        .map(entityToExpandedData).switchLatest()
        .subscribe(model => {
            $scope.model = model;
        });
    
    function entityToExpandedData (entity) {
        return Rx.Observable
            .zip(
                MemberService.getMember(d.ID),
                MemberService.dataOtherData(d.ID),
                MemberService.getNotes(d.ID),
                MemberService.getLog(d.ID),
                makeExpandedData
            );
    }
    
    function makeExpandedData (member, otherData, notes, log) {
        return {
            member:     member,
            otherData:  otherData,
            notes:      notes,
            log:        log
        };
    }