Josh Laird
Josh Laird

Reputation: 7224

RxKotlin flattenAsObservable(): type mismatch with method reference

I'm converting some Java code to Kotlin and I'm having some trouble with flattenAsObservable()

Here's what the code looked like in Java:

discogsInteractor.search(query)
    .map(RootSearchResponse::getSearchResults)
    .flattenAsObservable(searchResults -> searchResults)
    .take(12)

Here's what I have so far in Kotlin:

discogsInteractor.search(query)
    .map { RootSearchResponse::searchResults }
    .flattenAsObservable<SearchResult> { searchResults -> searchResults }
    .take(12)

It underlines the second searchResults and gives me the following error:

Required: (Mutable)Iterable<SearchResult!>!
Found: KProperty1<RootSearchResponse, List<SearchResult>>!

I can replace

.map { RootSearchResponse::searchResults }

with

.map { searchResponse -> searchResponse.searchResults }

and it will work. How do I correctly method reference? Or what's the reason that I can't in this instance?

RootSearchResponse:

data class RootSearchResponse(val pagination: Pagination,
                              @SerializedName("results") val searchResults: List<SearchResult>)

Upvotes: 1

Views: 685

Answers (1)

zsmb13
zsmb13

Reputation: 89578

RootSearchResponse::searchResults is a method reference. Instead of passing this to the map function, by using {}, you're passing in a lambda that always returns this method reference.

Basically, you're mapping every incoming element to that method reference with your map operation, instead of applying that method to every element like you'd want to. So the incoming parameters of your flattenAsObservable method are always that same reference to the searchResults method, which is a KProperty1.

To apply the method that you're referencing to every element, you can pass the method reference in regular parentheses, like so:

.map(RootSearchResponse::searchResults)

For an additional simple example of what's happening with the lambda:

listOf(1, 2, 3, 4, 5).map { 2 }

This operation would map every element to 2, and you'd end up with a list that only contains 2 five times. It's basically just shorthand for the following, just without an explicit parameter name:

listOf(1, 2, 3, 4, 5).map { x -> 2 }

Upvotes: 2

Related Questions