RxJs Working with exceptions without interruption

I'm not sure how correct I am on this, so if any experts can correct me this would be appreciated as well. My real understanding is that observables are lazy and do not give values ​​until they are signed. If an error occurs, the observable sends more values. In many cases, this is not what you want.

In the code example below, I get the weather for perth and london, and if an error occurs, it returns an object indicating the error. This pretty much means that the error block at the subscriber won't get called, but it will succeed and I'll have to see if it worked and the logic changed. Is this the best way to do it?

Also does the zip operator work for all obs to emit a value regardless of order and return when one value was created out of all?

Code below:

window.application = application || {};

window.application.stocks = (function(){


    function getWeather(city, country){

        return $.ajaxAsObservable({
            url: 'http://api.openweathermap.org/data/2.5/weather?q=' + city + ',' + country,
            dataType: 'jsonp'
        }).map(function(v){
            return {
                city : city,
                country : country,
                temperature : v.data.main.temp
            };
        });
    }

    var requests = Rx.Observable
                  .interval(500)
                  .timestamp()
                  .map(function(v){
                     var perth = getWeather('perth','au');
                     var london = getWeather('london','uk');

                     return Rx.Observable.zip(perth,london, function(a,b){
                         return {
                             a : a,
                             b : b,
                             timestamp : v.timestamp,
                             failure : false,
                         };
                     }).retry(3)
                       .catch(Rx.Observable.return({ failure: true }));

                   })
                  .concatAll();

    var selector = $('#weather');

    var subscriber = requests.forEach(
        function(data){

            if(data.failure){
                $('<li>Failure in receiving the temperature</li>').appendTo(selector);
                return;
            }

            $('<li> at: ' + data.timestamp + ' for: '  + data.a.city + ' - ' + data.a.temperature + '</li>').appendTo(selector);
            $('<li> at: ' + data.timestamp + ' for: '  + data.b.city + ' - '  + data.b.temperature + '</li>').appendTo(selector);
        },
        function(error){
            selector.text('');
            $('<li>Error: ' + error + '</li>').appendTo('#weather');
        },
        function(){

        }
    );

});

      

Any suggestions and advice is greatly appreciated.

Thanks in advance.

Blair.

+3


source to share


2 answers


You should probably replace .forEach()

with .subscribe()

, as it is an alias for the other and .subscribe()

is more common and more explicit in this case.

subscribe () can take three functions as arguments onNext

(first function), onError

(second function, optional), onComplete

(third function, optional). Hence, you will probably achieve what you want by simply providing a second function in subscribe () to handle errors. Then you don't need an operator .catch()

to insert the flag event.



Also, for your specific use case, where perth

both london

Observables and Observables are conceptually independent (they don't have dependencies with each other), you want to use .combineLatest()

instead .zip()

. See this answer for details on the difference between the two.

+3


source


Interestingly, this post says that you need to flag errors so that the steam does not terminate.

Idiomatic way to recover from onError stream



From my current RX understanding and testing, if an error occurs during the process, the subscription's onError handler will be called, but it will terminate the thread.

Meaning that the subscriber will not receive any additional messages.

0


source







All Articles