#android #kotlin #retrofit2 #clean-architecture #rx-java3
Вопрос:
Я хочу вызвать api, используя rxjava3 внутри функции getCampaigns в классе CampaignRepositoryImpl.kt, но я получаю следующую ошибку: выражение «возврат» требуется в функции с телом блока (‘ {…}’)
ниже класса CampaignRepositoryImpl.kt
import de.westwing.campaignbrowser.domain.Campaign
import de.westwing.campaignbrowser.domain.CampaignRepository
import io.reactivex.rxjava3.core.Single
class CampaignRepositoryImpl(private val apiInterface: ApiInterface) : CampaignRepository {
override fun getCampaigns(): Single<List<Campaign>> {
apiInterface.getCampaigns()
}
}
ниже моего класса интерфейса я получаю вызов API
interface ApiInterface {
@GET("cms/test/campaigns.json")
fun getCampaigns(): Single<CampaignsResponse>
}
ниже представлен отчет о кампании
кампания по взаимодействию {
fun getCampaigns(): Single<List<Campaign>>
}
ниже моего сравнительного ответа.kt
data class CampaignsResponse(val metadata: CampaignsMetadata)
ниже КампаингсМетадата
data class CampaignsMetadata(val data: List<CampaignDto>)
ниже
data class Campaign(val name: String, val description: String)
ниже приведена кампания по
class CampaignDto(val name: String, val description: String, val image: ImageDto)
Я хочу знать, где я совершаю ошибку, что я должен делать, чтобы избежать ошибки
Комментарии:
1. Эээ, вам нужно что-то вернуть из функции?
return apiInterface.getCampaigns()
2. даже если я возвращаюсь, я получаю ту же ошибку
3. @broot Я делаю в точности так, как вы сказали, но я получаю следующее несоответствие типа ошибки. Требуется: Один<Список<Кампания><Кампания>> Найдено: Один<Ответ на кампанию>
4. Да, но это сообщение об ошибке также является довольно описательным. Ваши
ApiInterface.getCampaigns()
возвратыSingle<CampaignsResponse>
, но вам нужно вернутьсяSingle<List<Campaign>>
из внешней функции, поэтому вам нужно преобразовать первую во вторую. Я предполагаюCampaignResponse
, что он содержитсяList<Campaign>
где-то внутри.5. @брут, можете ли вы объяснить свой ответ примером кодирования
Ответ №1:
Из вашего интерфейса api мы видим, что тип getCampaigns()
is Single<CampaignsResponse>
. С другой стороны, в вашей реализации репозитория тип getCampaigns()
is Single<List<Campaign>>
.
Так как Single<Foo>
и то , и другое, вам нужно будет переходить map
от одного к другому.
Учитывая ваши реализации классов, это должно сработать:
override fun getCampaigns(): Single<List<Campaign>> {
return apiInterface.getCampaigns().map { response ->
response.metadata.data.map {
Campaign(it.name, it.description)
}
}
}
Этот map
вызов берет а CampaignResponse
и превращает его в а List<Campaign>
.
Комментарии:
1. можете ли вы проверить мой обновленный код, я получаю следующую ошибку
2. На вашем скриншоте показана
entity
посылка сCampaignResponse
иCampaignMetadata
, а такжеdomain
посылка сCampaign
. Нам нужно будет просмотреть содержимое этих файлов, чтобы предоставить дополнительные сведения.3. Я добавил CampaignResponse и CampaignMetadata, а также пакет домена с кампанией
4. @BenP. Пожалуйста, замените
it.campaigns
в своем ответе:it.metadata.data.map { Campaign(it.name, it.description) }
— только для будущих читателей.
Ответ №2:
Поскольку ваш ApiInterface возвращает один, вы можете просто вернуть его в теле метода. Возможно, вам придется проверить, что у CampaignRepository есть метод getCampaigns (), и он должен возвращать один.
class CampaignRepositoryImpl(private val apiInterface: ApiInterface) : CampaignRepository {
override fun getCampaigns(): Single<CampaignsResponse> {
return apiInterface.getCampaigns()
}
}