Search code examples
androidkotlinretrofitkotlin-flow

How to use Zip operator of kotlin flow in Android


In my application I want combine two deferent API with ZIP operator of Kotlin flow.!
Api 1 is Movies list and Api 2 is genres list!
I want loaded each 2 Apis in one time, for this I used zip operator!
My work is true? Can I combine 2 deferent Apis with them?

ApiServices :

interface ApiServices {
    @GET("movies")
    suspend fun moviesList(): Response<MoviesList>

    @GET("genres")
    suspend fun genresList(): Response<GenresList>
}

Repository class:

class Repository @Inject constructor(private val api: ApiServices) {

    suspend fun moviesList(): Flow<Response<MovieList>> {
        return flow {
            emit(api.moviesList(1))
        }
    }

    suspend fun genresList(): Flow<Response<GenresList>> {
        return flow {
            emit(api.genresList())
        }
    }
}

I know show error for add deferent model class in moviesList !

But I want know how can I use Zip operator for combine 2 deferent Apis?


Solution

  • You could use combine(flow1,flow2) method to combine the flow and zipping your api response using zip , for example :

    class ViewModel @Inject constructor(private val repository: Repository) : ViewModel() {
    
        val moviesFlow = repository.moviesList()
        val genresFlow = repository.genresList()
    
        fun loadMoviesAndGenres() : Flow<List<Pair<Type1,Type2>>> = combine(moviesFlow, genresFlow) { movieList: Response<MovieList>, genreList:Response<GenresList> ->
           val movies = movies.body()?.data
           val genres = genres.body()
           return@combine movies?.zip(genres)
        }
    }
    
    

    How to use zip :

    val listMovieTittle = listOf("avanger", "conjuring", "other")
    val listGenre = listOf("action", "horror", "fantasy", "thriller")
    
    val result1 : List<Pair<String,String>> = listMovieTittle .zip(listGenre)
    println(result1 ) // [(avanger, action), (bconjuring, horror), (other, fantasy)]
    
    val result2  : List<String> = listMovieTittle .zip(listGenre) { a, b -> "$a + $b" }
    println(result2) // [avanger + action, conjuring + horror, other + fantasy]