Reputation: 2798
I query the youtube api and made several models to map the json with gson converter. Now I want to use repository pattern and unify the return value from my database and from remote, but I have some issues to know how to return a specific variable from an observable in RxJava.
I query the api like this:
@GET("playlistItems?part=snippet")
fun getLatestVideosFromPlaylist(@Query("playlistId") playlistId:String, @Query("maxResults") maxResults:String): Observable<YoutubeVideosModel>
My models
data class YoutubeVideosModel(
@SerializedName("items")
val videos: ArrayList<YoutubeVideo>
)
@Entity(tableName = "video")
data class YoutubeVideo(
@PrimaryKey(autoGenerate = true)
val id: Int? = null,
@SerializedName("snippet")
val video: YoutubeVideoData
)
My data source interface
interface VideoDataSource {
fun fetchVideos(playlistId:String) : Observable<ArrayList<YoutubeVideo>>
}
From my local data source I return a arrayList of youtubeVideo
object VideoLocalSource: VideoDataSource {
override fun fetchVideos(playlistId: String): Observable<ArrayList<YoutubeVideo>> {
return Observable.fromCallable {
AppDatabase.getInstance(BaseApp.INSTANCE)?.getVideoDao()!!.fetchAllVideos()
}
}
}
But from my remote I cannot find how to return the same:
object VideoRemoteSource: VideoDataSource {
override fun fetchVideos(playlistId: String, maxResults:String): Observable<ArrayList<YoutubeVideo>> {
YoutubeApiClient.getYoutubeService().getLatestVideosFromPlaylist(playlistId, maxResults)
.subscribe {
videoModel ->
//Here cannot use return
return ObservableFromArray(arrayOf(videoModel.videos)
}
}
}
Upvotes: 2
Views: 284
Reputation: 2165
What you are having difficulty with is the way asynchronous programming requires you to think. Returning an observable inside a subscription callback is not valid. Because you don't know when the subscriber will be called
For a case like this where you want to return an observable of what you are fetching asynchronously, you can use a map like below.
object VideoRemoteSource: VideoDataSource {
override fun fetchVideos(playlistId: String): Observable<List<YoutubeVideo>> {
return youtubeApiService.getLatestVideosFromPlaylist(playlistId, "3")
.flatMap{
Observable.fromArray(it.videos)
}
}
}
Upvotes: 1