Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Observable pattern on reactive extension

I am trying to understand the below code trying to use reactive extensions

 IObservable<string> textChangedObservable =
            Observable.FromEventPattern<TextChangedEventArgs>(searchScrip, "TextChanged")
                .Select(evt => ((TextBox) sender).Text);

 textChangedObservable.Subscribe(OnNext, OnCompleted);

private void OnNext(string s)
    {
        System.Diagnostics.Debug.Print("OnNext " + s + "\n");
    }

    private void OnCompleted()
    {
        System.Diagnostics.Debug.Print("OnCompleted " + "\n");
    }

If I enter SEARC in the input box, the output looks

  • OnNext SE
  • OnNext SEA
  • OnNext SEA
  • OnNext SEAR
  • OnNext SEAR
  • OnNext SEAR
  • OnNext SEARC
  • OnNext SEARC
  • OnNext SEARC
  • OnNext SEARC

    1. Why is "S" not triggering an OnNext?
    2. Why is OnCompleted never called?
    3. Why is the OnNext called n-1 time on the nth character?
like image 554
asb Avatar asked Sep 04 '15 12:09

asb


People also ask

Is reactive programming Observer pattern?

'ReactiveX is a combination of the best ideas from the Observer pattern, the Iterator pattern, and functional programming'. So it is not functional programming, but uses some ideas from functional programming.

What is an Observable in reactive programming?

An Observable is simply a collection of data that waits to be invoked (subscribed) before it can emit any data. If you've worked with promises, then the way to access the data is to chain it with the then() operator or use the ES6 async/await .

What is the main design pattern of the reactive programming?

Reactive programming describes a design paradigm that relies on asynchronous programming logic to handle real-time updates to otherwise static content. It provides an efficient means -- the use of automated data streams -- to handle data updates to content whenever a user makes an inquiry.

What is a reactive pattern?

Reactive Design Patterns is a clearly written guide for building message-driven distributed systems that are resilient, responsive, and elastic. In this book you'll find patterns for messaging, flow control, resource management, and concurrency, along with practical issues like test-friendly designs.


2 Answers

It appears that you are subscribing to the observable in your searchScrip_TextChanged handler.

This means that the first time that searchScrip_TextChanged gets called the S has already happened before you've wired up the observable. So of course it doesn't fire.

But now that the S is hit you have one subscription so when the E is typed you get a single SE. But since the searchScrip_TextChanged handler gets called for the E too you now have two subscriptions to your observable.

So when the A is typed you get two SEA because you have two observables. But again the searchScrip_TextChanged is called for the A so now you have three observables.

Etc, etc, etc.

Events don't complete automatically. You need to manually dispose of the subscriptions to have them end. This should make sense because that's what you have to do with normal event handlers that you want to stop.

You should create your observable when your form is loaded so that it is created once.

It should look like this:

IObservable<string> textChangedObservable =
        Observable.FromEventPattern<TextChangedEventArgs>(searchScrip, "TextChanged")
            .Select(evt => searchScrip.Text);

IDisposable subscription =
    textChangedObservable
        .Subscribe(
            s => Debug.Print("OnNext " + s + "\n"),
            s => Debug.Print("OnCompleted\n"));
like image 89
Enigmativity Avatar answered Oct 06 '22 01:10

Enigmativity


The problem here really has nothing to do with Rx.

1: Why is "S" not triggering an OnNext?

Because the TextChanged event you have subscribed to did not fire on the first S.

2: Why is OnCompleted never called?

When you wrap a .NET event as an IObservable<T>, you never get OnError or OnCompleted notifications. There is no concept of error or completion with a .NET event.

If there are two events, one for values and one for completion, you can combine them like so:

var values = Observable.FromEvent(...);
var completion = Observable.FromEvent(...);
var query = values.TakeUntil(completion);

Now query will yield a proper OnCompleted notification.

3: Why is the OnNext called n-1 time on the nth character?

Because the TextChanged event you have subscribed to fired this way. As was pointed out by @Kari-Antti, this may be a side effect of using a "routed property" event.

like image 20
Timothy Shields Avatar answered Oct 06 '22 01:10

Timothy Shields