Mapping Data to Data

Both RxJava and LiveData offer a map() transformation. As seen in the preceding section, a map() converts an item of data from the stream (e.g., a String) to some other item of data to flow downstream (e.g., an uppercase String).

However, whereas map() is a method on RxJava’s Observable and related classes, with LiveData, the transformations are held in a separate Transformations class.

For example, suppose we have a DAO method like:

@Query("SELECT * FROM Customer")
LiveData<List<Customer>> allCustomers();

Here, we are expecting a stream of results, where each item is the result of the query: a list of customers. Room will deliver the current customers to us quickly, then will deliver updated lists of customers as the Customer table changes, so long as we are observing the LiveData.

Suppose, though, we do not need the Customer objects, but instead need their IDs. The simplest and most performant solution would be to have a different DAO method:

@Query("SELECT id FROM Customer")
LiveData<List<String>> allCustomerIds();

However, that does not use Transformations, and so it is boring. Plus, not every possible transformation is simply cutting a POJO down to a single field from that POJO.

The Transformations equivalent would be something like this:

LiveData<List<String>> liveCustomerIds=
  Transformations.map(store.allCustomers(),
    new Function<List<Customer>, List<String>>() {
      @Override
      public List<String> apply(List<Customer> customers) {
        ArrayList<String> result=new ArrayList<>();

        for (Customer customer : customers) {
          result.add(customer.id);
        }

        return(result);
      }
    });

map() takes two parameters: a LiveData of the stream to manipulate, and a Function that converts items from that stream from one data type to another.

Here is where Room’s insistence on a single-object response becomes a pain. If this were a stream of Customer objects, our Function could just get the id from the Customer and return it. But we do not have a stream of Customer objects — we have a stream of a list of Customer objects. That means we need to return a list of customer IDs, requiring allocating a new ArrayList and iterating over each Customer to add its id to that list.


Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.