lineage
lineage

Reputation: 895

Efficient Transformations of LiveData<List> to another LiveData<List>

Consider some generic @Entity User stored in a Room db. Some @Dao retruns a LiveData<List<User>> aka 'dao result'. I wish to create another live list where each element is a transform of the dao result, say

LiveData<List<UserWrapper>>

//UserWrapper needs a User to construct

So I write something like

 Transformations.map(daoResult,list -> {

            
            List<UserWrapper> newList=new ArrayList<>(list.size());
            list.forEach(user -> {
               newList.add(new UserWrapper(user));
            });

            return newList;
        });

If my understanding of LiveData is correct, the dao result only responds to List level changes, say the list is added to, subtracted from etc. and not if the underlying User object is or its fields are changed.

  1. Is this correct?

Say some changes are made in the db which have made some new records eligible to be in the result set of the underlying dao result's @Query

  1. Would the LiveData<List<User>>, the query result, automatically reflect that? Would the Transformations.map carry it forth to LiveData<List<UserWrapper>>?

In the above implementation every time the underlying list is modified, the map is creating a new List and reinitializing it which to me seems inefficient and wrong somehow. Why should one have to do the manual checking of of both lists to ensure consitent transformed state?

  1. Is there a better way to do this so that there is always a 1-1 correspondence between the Users and UserWrappers?

Upvotes: 0

Views: 86

Answers (1)

sergiy tykhonov
sergiy tykhonov

Reputation: 5103

I'm not sure I've got the point of your question, but consider my thoughts:

  1. When you use LiveData as a query's return type, Room sets for you some kind of callback. So if you use select * from users ... in your query, then EACH change to table users triggers updating LiveData's value (it's not obvious, so I mean - EACH change, even if some user has been changed that is not in your result list).
  2. In theory you can get from the query to table user not only List<User>, but List<UserWrapper> as well. It depends on the UserWrapper and User structures. For that you should write a query with fields that match to UserWrapper fields, or to use Room's Relations.

Upvotes: 1

Related Questions