Reactivejs autocomplete forking pipeline

Viewed 136

Im going through some Reactivejs tutorial, and i'm implementing autocomplete with rx.js.

It looks great, but i wonder how to achieve some functionality. Look at this code:

const $title = $('#title'); // input element
const $results = $('#result');

Rx.Observable.fromEvent($title, 'keyup')
    .map(event => event.target.value.trim())
    .distinctUntilChanged()
    .debounceTime(500)
    .switchMap(getItems) // getItems sends request for result based on input value and returns promise
    .subscribe(items => {
        $results.empty();
        $results.append(items.map(record => $('<li> /').text(record)));
    });

This works great, I can get updated list on input value change. But in case user has cleared input completely, I want to prevent from request to be sent. I can achieve it using filter:

Rx.Observable.fromEvent($title, 'keyup')
    .map(event => event.target.value.trim())
    .filter(query => query.length > 0)
    .distinctUntilChanged()
    .debounceTime(500)
    .switchMap(getItems)
    .subscribe(items => {
        $results.empty();
        $results.append(items.map(record => $('<li> /').text(record)));
    });

but in case user has cleared this input I don't want to send additional request and I want load default list of items.

How can i achieve that?

Is there a way to capture new entry in observable collection and in case it is empty string disrupt processing pipe but somehow still subscribe for it?:

 Rx.Observable.fromEvent($title, 'keyup')
        .map(event => event.target.value.trim())

        // CHECK IF INPUT VALUE IS EMPTY STRING, NAD IF IT IS
        // PREVENT PIPELINE STEPS BELOW FROM BEING PROCESSED.
        // ALSO SHOW DEFAULT LIST ITEMS

        .distinctUntilChanged()
        .debounceTime(500)
        .switchMap(getItems)
        .subscribe(items => {
            $results.empty();
            $results.append(items.map(record => $('<li> /').text(record)));
        });

I've tried implementing it this way:

const query$ = Rx.Observable.fromEvent($title, 'keyup')
    .map(event => event.target.value.trim());

query$
    .filter(query => query.length > 0)
    .distinctUntilChanged()
    .debounceTime(500)
    .switchMap(getItems)
    .subscribe(items => {
        $results.empty();
        $results.append(items.map(record => $('<li> /').text(record)));
    });

query$.subscribe(query => {
    if (!query.length) {
        $results.text('default list'); // this list will still be overwritten with last fetch result
    }
});

But last response for query still calls my subscribe listener and populates list with the results.

2 Answers
Related