Reactive GWT


Introduction

Reactive programming’s popularity has tremendously grown over the last 4 or 5 years. This can tell us that the use case of reactive applications is now valid more than ever. The strain on backend systems has increased and accordingly the need to handle this strain with minimal resources. Reactive programming is seen as a way to increase efficiency and throughtput while reducing resource consumption. The popularity of reactive programming led to the development of reactive extensions for most of the programming languages and platforms: GWT is no exception. In this post, we will provide an example of usage for rxjava-gwt which is the reactive extension for GWT.

About rxjava-gwt

rxjava-gwt is the adaptation of RxJava to GWT, and not a wrapper for RxJs as some may believe. According to the project creator Ignacio Baca, adapating RxJava to GWT is more useful than wrapping RxJs, expecially if the Rx code is shared between the client and the server, because here the behaviour is exactly the same. Also, this introduces the possibility of sharing custom operators or Rx compositions.

Use Cases

From a backend point of view, reactive programming is seen as way to increase efficiency and throughtput, and to achieve requests with the minimal resource consumption, but how about the front-end ? Well, we know that JavaScript is inherently asychronous and the usage of callbacks/Promises is common, so what does reactivity has to add? First, it can help make the application more responsive if the application is calling external datasources (e.g HTTP requests, websockets, server sent events) by transforming those sources into a stream and reacting as data pours in rather than waiting for the integrity of the data to be available. Second, reactive programming can help combine several event sources into one main stream if the action to be taken is common.

Example

Suppose we want to create a simple UI for the famous curl library. We want to have three fields (url, method, and body data), and we want our curl command to be generated as we type along. This looks like a good use case to introduce reactive programming as we have several event sources that require the same kind of processing. Using the traditional mode of programming, we would have to do the same action for every event handler.

HTML

 <div class="form-container">
    <label for="url">URL:</label>
    <input id="url" type="text"></input>
    <label for="method">Method: </label>
    <select id="method">
      <option selected value="GET">GET</option>
      <option value="POST">POST</option>
      <option value="PUT">PUT</option>
      <option value="DELETE">DELETE</option>
      <option value="PATCH">PATCH</option>
      <option value="HEAD">HEAD</option>
      <option value="OPTIONS">OPTIONS</option>
      <option value="CONNECT">CONNECT</option>
      <option value="TRACE">TRACE</option>
    </select>
    <label for="data">Data: </label>
    <textarea id="data"></textarea>
    <div id="result">curl <span id="generatedCommand"></span></div>
  </div>

Code:

  HTMLInputElement urlInput = (HTMLInputElement) DomGlobal.document.getElementById("url");
  HTMLSelectElement methodInput = (HTMLSelectElement) DomGlobal.document.getElementById("method");
  HTMLTextAreaElement dataInput = (HTMLTextAreaElement) DomGlobal.document.getElementById("data");
  HTMLElement generatedCommand = (HTMLElement) DomGlobal.document.getElementById("generatedCommand");
  final String[] commands = new String[3];

    Observable urlStream = Observable.create((emitter) -> {
      urlInput.onkeyup = (event) -> {
        HTMLInputElement urlInputTarget = (HTMLInputElement) event.target;
        emitter.onNext(new Command(2, urlInputTarget.value));
        return null;
      };
    });

    Observable methodStream = Observable.create((emitter) -> {
      methodInput.onchange = (event) -> {
        HTMLSelectElement methodSelect = (HTMLSelectElement) event.target;
        emitter.onNext(new Command(1, "-X"+methodSelect.value));
        return null;
      };
    });


    Observable dataStream = Observable.create((emitter) -> {
      dataInput.onkeyup = (event) -> {
        HTMLTextAreaElement dataInputTarget = (HTMLTextAreaElement) event.target;
        emitter.onNext(new Command(3, "-d '"+dataInputTarget.value+"'"));
        return null;
      };
    });

    Observable.merge(urlStream, methodStream, dataStream).subscribe((obs) -> {
      commands[obs.position - 1] = obs.value;
      generatedCommand.textContent = String.join(" ", Stream.of(commands)
                                                            .filter(Objects::nonNull)
                                                            .collect(Collectors.toList()));
    });

  }
}

Conclusion

rxjava-gwt opens the doors to the reactive world for GWT developers. We have seen some use cases that make sens for reactive programming to be used, so it is about time for GWT developers to try the reactive model in their applications when it make sens.

Source code: https://github.com/zak905/reactive-gwt

Other examples:

Looking for more GWT material ? Check out our new GWT course on Udemy.

Tagged with:

Archive

Blog Partners