Is it possible to get rid of nested Task generics?
For every continueWith
statement, a new Task
is added within the type. Every continuation is part of the type. Ideally I would return one Task which consecutively executes every single task and succeeds or fails as one.
The first operations queries the groups of a user
private fun getGroupsSnapshot(): Task<QuerySnapshot> {
val userId = Auth.currentUser()!!.uid
val query = userGroupsQuery(groupsCollection, userId)
return query.get()
}
The second operation queries albums within those groups.
fun getAlbums(): Task<Task<List<Album>>> {
return getGroupsSnapshot().continueWith { task ->
val documentSnapshots = TaskUtils.getResult(task)
val albums = mutableListOf<Album>()
val fetchAlbumTasks = documentSnapshots.documents.map { document ->
Log.d(TAG, document["name"].toString())
document.reference.collection("albums").get().addOnCompleteListener { queryTask ->
albums.addAll(toObjects(Album::class.java, queryTask))
}
}
return@continueWith Tasks.whenAll(fetchAlbumTasks).continueWith allTasks@ {
return@allTasks albums as List<Album>
}
}
}
However I would like this operation to return type Task<List<Album>>
to keep the interface clean.
For composing multiple Task
you should use continueWithTask
instead of continueWith
. It accepts a Continuation<TResult, Task<TContinuationResult>
as a parameter, which essentially flattens the returning Task
and avoids nesting. You should think of it as map
vs flatMap
operation in Monads (i.e. List
), in this case, continueWithTask
would be the equivalent of flatMap
if you use List
as the container instead of Task
(Remember, with flatMap
you transform every element of the List
to a new List
, and flatten the resulting List
)