Any suggestions/ideas to fetch paginations list un...
# orbit-mvi
m
Any suggestions/ideas to fetch paginations list until it becames empty in one
intent
? Our attempts in 🧵
Copy code
/**
 * Trying to paginate internally until [categoriesEnds] [isEmpty]
 */
fun getAgentJobCategoriesFromWorkExperiences() = intent {
    var (page, limit) = 1 to 5
    var categoriesEnds = listOf<String>()
    val jobCategories = mutableListOf<String>()

    do {
        try {
            // when last page or empty, it'll reassign the categoriesEnds with empty list
            categoriesEnds = loadWorkExperienceUseCase(params = Pair(page++, limit))
                .map { workExperiences ->
                    workExperiences.map { workExperience -> workExperience.jobCategoryName }
                }
                .single()

            jobCategories.addAll(categoriesEnds)
            
        } catch (e: AnyException) {
            // do nothing for now?
        }
    } while (categoriesEnds.isNotEmpty())

    reduce {
        kotlin.runCatching {
            state.copy(jobCategoriesFromWorkExperiences = jobCategories.orEmpty())
        }.getOrElse {
            state.copy(jobCategoriesFromWorkExperiences = emptyList())
        }
    }
}
We were unable to properly test this using mock, maybe missing something in our part?
Copy code
@Test
fun `get agent job categories from work experiences - success`() = runBlockingTest {
    val dummyJobCategories = mutableListOf<WorkExperience>()

    for (i in 1..5) {
        dummyJobCategories.add(
            JobCategoriesWorkExperiences(
                id = "",
                workIndustryName = "",
                jobPosition = "",
                jobCategoryName = "Category $i",
                companyName = "",
                startYear = "",
                endYear = "",
                jobDescriptions = listOf(),
            )
        )
    }

    getWorkExperiences.stub {
        on { invoke(1 to 5) } doReturn dummyJobCategories.asFlow()
    }

    val initialState = HomeViewState(
        jobCategoriesFromWorkExperiences = emptySet(),
    )

    viewModel
        .test(initialState = initialState)
        .runOnCreate()
        .testIntent {
            getAgentJobCategoriesFromWorkExperiences()
        }
        .assert(initialState = initialState) {
            states(
                {
                    copy(jobCategoriesFromWorkExperiences = dummyJobCategories.map { it.jobCategoryName }
                        .toSet())
                }
            )
        }
}
It always throws:
Copy code
java.lang.NullPointerException
at com.company.activities.main.home.HomeViewModel$getAgentJobCategoriesFromWorkExperiences$1$invokeSuspend$$inlined$map$1.collect(SafeCollector.common.kt:114)
at kotlinx.coroutines.flow.FlowKt__ReduceKt.single(Reduce.kt:179)
at kotlinx.coroutines.flow.FlowKt.single(Unknown Source)
at com.company.activities.main.home.HomeViewModel$getAgentJobCategoriesFromWorkExperiences$1.invokeSuspend(HomeViewModel.kt:358)
at com.company.activities.main.home.HomeViewModel$getAgentJobCategoriesFromWorkExperiences$1.invoke(HomeViewModel.kt)
at com.company.activities.main.home.HomeViewModel$getAgentJobCategoriesFromWorkExperiences$1.invoke(HomeViewModel.kt)
at org.orbitmvi.orbit.syntax.simple.SimpleSyntaxExtensionsKt$intent$1$1$1.invokeSuspend(SimpleSyntaxExtensions.kt:76)
at org.orbitmvi.orbit.syntax.simple.SimpleSyntaxExtensionsKt$intent$1$1$1.invoke(SimpleSyntaxExtensions.kt)
at org.orbitmvi.orbit.syntax.simple.SimpleSyntaxExtensionsKt$intent$1$1$1.invoke(SimpleSyntaxExtensions.kt)
at org.orbitmvi.orbit.idling.SimpleIdlingExtensionsKt.withIdling(SimpleIdlingExtensions.kt:30)
Finally, we’re able to solve the above issues by extracting the
do-while
loop to our use case (and leave the orbit-mvi to returns the data directly, without any business logic)
we also implement test case in our use case, and orbit-mvi unit test became simpler (w/o NPE)