4

I have implemented Pager 3 for my RecyclerView. Now I have to add a header to my recycler view if the API response has a flag set.

What I am doing now is when i get the response, I set this flag to a static variable then in the ViewModel check for this variable before adding header like this:

//PagingDataSource
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, UIModel> {
        val position = params.key ?: STARTING_PAGE_INDEX
        val response = getUseCase(
            orgId = orgId,
            isPhysical = null,
            limit = params.loadSize,
            page = position
        )
    // SETTING FLAG HERE
    AppVariable.SessionData.myFlag = response.data.flag ?:false
    return LoadResult.Page(
                        data = response.data.data,
                        prevKey = if (position == STARTING_PAGE_INDEX) null else position - 1,
                        nextKey = if (data.isEmpty()) null else position + 1
                    )
}

In viewModel i am checking like this:

 fun fetchData(): Flow<PagingData<UIModel>> {
     val flow = Pager(
            ...
            pagingSourceFactory = {
                PagingDataSource(
                    ...
                )
            }
        ).flow
            .map { pagingData ->
                //ISSUE HERE
                if (AppVariables.SessionData.myFlag) { 
                        return@map pagingData.insertHeaderItem(
                            TerminalSeparatorType.SOURCE_COMPLETE,
                            UIModel.ActivateCardHeader
                        )
                    }
                pagingData
                }
             return flow
     }

Now the issue is that the if condition is getting invoked before I get the response from the server, and after I get the response from the server this if condition is not getting invoked(I know this because I tried setting debug points and it's not hitting after the API response.) If call recyclerViewAdapter.refresh() my header becomes visible.

How can I fix this issue?

hushed_voice
  • 3,161
  • 3
  • 34
  • 66

2 Answers2

0

I know 2 possible ways to this solution

  1. Create a function and call it after getting the response from the API inside the onResponse method.
  2. or Try using a callback for the response like

Using Callback

interface MyCallback {
        fun onResponse(flag: Boolean)
    }

and inside your own response after getting the result call the onResponse method using the instance MyCallback instance and modify the recycler view inside the overridden onResponse method according to flag parameter.

To learn about interfaces, check out link

Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
Sidharth Mudgil
  • 1,293
  • 8
  • 25
0

The AppVariables.SessionData.myFlag type must be a flow or state flow then you can use map and flattenConcact operator to achive this functionallity. your code must be like this:

    fun fetchData(): Flow<PagingData<UIModel>> {
        return AppVariables.SessionData.myFlag.map { myFlag ->
            Pager(
                ...
            pagingSourceFactory = {
                PagingDataSource(
                    ...
                )
            }).flow.map { pagingData ->
                if (myFlag) {
                    pagingData.insertHeaderItem(
                    TerminalSeparatorType.SOURCE_COMPLETE,
                    UIModel.ActivateCardHeader
                    )
                }
                pagingData
            }
        }.flattenConcat()
    }

with map operator in every change in flag new instance of pager will be returned. flattenConcat operator for convert Flow<Flow<Any>> to Flow<Any>

Mobin Yardim
  • 695
  • 7
  • 17