K.Os
K.Os

Reputation: 5496

Error when changed lambda for flatmap of two Observables to flatmap of two Singles

I want to combine results of two API requests. Initially i made them return Observable, but to perform it correctly i guess the response should be a Single.

Here are my initial Retrofit interefaces:

interface RemoteGeocodingService {

@GET("json")
fun requestCityAddressByName(
        @Query("address") address: String
): Observable<LocationResponse>
}

interface RemoteWeatherService {

@GET("{latitude},{longitude}")
fun requestWeatherForCity(
        @Path("latitude") latitude: String,
        @Path("longitude") longitude: String
): Observable<WeatherResponse>
}

I was combining the results of them like this, using lambda:

    override fun getWeather(cityName: String): Observable<WeatherDetailsDTO>? {
    return remoteWeatherDataSource.requestCityAddressByName(cityName)
            .flatMap({ responseFromServiceA -> remoteWeatherDataSource.requestWeatherForCity(responseFromServiceA.results[0].geometry.location.lat.toString(), responseFromServiceA.results[0].geometry.location.lng.toString()) },
                    { responseFromServiceA, responseFromServiceB ->
                        TransformersDTO.transformToWeatherDetailsDTO(responseFromServiceA.results[0].formatted_address, responseFromServiceB)
                    })
            .retry()
}

However, when i change the result of request for each API interface method to use Single instead of Observable i am not able to perform this - I get error in Android Studio IDE editor. Here is what i tried:

  override fun getWeather(cityName: String): Single<WeatherDetailsDTO> {
    return remoteWeatherDataSource.requestCityAddressByName(cityName)
            .flatMap({ responseFromServiceA: LocationResponse -> remoteWeatherDataSource.requestWeatherForCity(responseFromServiceA.results[0].geometry.location.lat.toString(), responseFromServiceA.results[0].geometry.location.lng.toString()) },
                    { responseFromServiceA: LocationResponse, responseFromServiceB: WeatherResponse ->
                        TransformersDTO.transformToWeatherDetailsDTO(responseFromServiceA.results[0].formatted_address, responseFromServiceB)
                    })
            .retry()

The IDE marks as error .flatMap operator and says:

None of the following functions can be called with the arguments supplied. flatMap(((t: LocationResponse) → SingleSource!)!)   where R cannot be inferred for   fun flatMap(mapper: ((t: LocationResponse) → SingleSource!)!): Single! defined in io.reactivex.Single flatMap(Function!>!)   where R cannot be inferred for   fun flatMap(mapper: Function!>!): Single! defined in io.reactivex.Single

How it can be resolved?

Upvotes: 1

Views: 651

Answers (1)

akarnokd
akarnokd

Reputation: 69997

There is no Single.flatMap(Function, BiFunction) method. You have to map onto the inner result to get the items paired up:

remoteWeatherDataSource.requestCityAddressByName(cityName)
    .flatMap({ a: LocationResponse ->
        remoteWeatherDataSource.requestWeatherForCity(
            a.results[0].geometry.location.lat.toString(), 
            a.results[0].geometry.location.lng.toString()
        )
        .map { b: WeatherResponse ->
            TransformersDTO.transformToWeatherDetailsDTO(
                a.results[0].formatted_address, 
                b
            )
        } 
    })

Upvotes: 3

Related Questions