title: Android Paging 3: How to change parameters of RemoteMediator
body: <p>I am struggling with the Paging 3 Library of Jetpack.</p>
  <p>I setup</p>
  <ul>
  <li>Retrofit for the network API calls</li>
  <li>Room to store the retrieved data</li>
  <li>A repository that exposes the Pager.flow (see code below)</li>
  <li>A RemoteMediator to cache the network results in the room database</li>
  </ul>
  <p>The <code>PagingSource</code> is created by Room.</p>
  <p>I understand that the <code>RemoteMediator</code>s responsibility is to fetch items from the network and persist them into the Room database. By doing so, we can use the Room database as single point of truth. Room can easily create the <code>PagingSource</code> for me as long as I am using Integers as <code>nextPageKeys</code>.</p>
  <p>So far so good. Here is my ViewModel to retrieve a list of <code>Sources</code>:</p>
  <pre><code>    private lateinit var _sources: Flow&lt;PagingData&lt;Source&gt;&gt;
      val sources: Flow&lt;PagingData&lt;Source&gt;&gt;
          get() = _sources
  
      
      private fun fetchSources() = viewModelScope.launch {
          _sources = sourcesRepository.getSources(
              selectedRepositoryUuid,
              selectedRef,
              selectedPath
          )
      }
  </code></pre>
  <p><code>val sources</code> is collected in the <code>Fragment</code>.</p>
  <p><code>fetchSources()</code> is called whenever one of the three parameters change (<code>selectedRepositoryUuid</code>, <code>selectedRef</code> or <code>selectedPath</code>)</p>
  <p>Here is the Repository for the Paging call</p>
  <pre><code>    fun getSources(repositoryUuid: String, refHash: String, path: String): Flow&lt;PagingData&lt;Source&gt;&gt; {
          return Pager(
              config = PagingConfig(50),
              remoteMediator = SourcesRemoteMediator(repositoryUuid, refHash, path),
              pagingSourceFactory = { sourcesDao.get(repositoryUuid, refHash, path) }
          ).flow
      }
  </code></pre>
  <p>Now what I experience is that <code>Repository.getSources</code> is first called with correct parameters, the <code>RemoteMediator</code> and the <code>PagingSource</code> are created and all is good. But as soon as one of the 3 parameters change (let's say <code>path</code>), neither the RemoteMediator is recreated nor the PagingSource. All requests still try to fetch the original entries.</p>
  <h3>My question: How can I use the Paging 3 library here in cases where the paging content is dependent on dynamic variables?</h3>
  <p>If it helps to grasp my use-case: The RecyclerView is displaying a paged list of files and folders. As soon as the user clicks on a folder, the content of the RecyclerView should change to display the files of the clicked folder.</p>
  <hr />
  <p>Update:</p>
  <p>Thanks to the answer of dlam, the code now looks like this. <strong>The code is a simplification of the real code. I basically encapsulate all needed information in the <code>SourceDescription</code> class.</strong>:</p>
  <p>ViewModel:</p>
  <pre><code>    private val sourceDescription = MutableStateFlow(SourceDescription())
  
      fun getSources() = sourceDescription.flatMapConcat { sourceDescription -&gt;
  
          // This is called only once. I expected this to be called whenever `sourceDescription` emits a new value...?
  
          val project = sourceDescription.project
          val path = sourceDescription.path
  
          Pager(
              config = PagingConfig(30),
              remoteMediator = SourcesRemoteMediator(project, path),
              pagingSourceFactory = { sourcesDao.get(project, path) }
          ).flow.cachedIn(viewModelScope)
      }
  
      fun setProject(project: String) {
          viewModelScope.launch {
              val defaultPath = Database.getDefaultPath(project)
              val newSourceDescription = SourceDescription(project, defaultPath)
              sourceDescription.emit(newSourceDescription)
          }
      }
  </code></pre>
  <p>In the UI, the User first selects a project, which is coming from the <code>ProjectViewModel</code> via LiveData. As soon as we have the project information, we set it in the <code>SourcesViewModel</code> using the <code>setProject</code> method from above.</p>
  <p>Fragment:</p>
  <pre><code>    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
          super.onViewCreated(view, savedInstanceState)
  
          // load the list of sources
          viewLifecycleOwner.lifecycleScope.launchWhenStarted {
              sourcesViewModel.getSources().collectLatest { list -&gt;
                  sourcesAdapter.submitData(list) // this is called only once in the beginning
              }
          }
  
          projectsViewModel.projects.observe(viewLifecycleOwner, Observer { project -&gt; 
              sourcesViewModel.setProject(project)
          })
      }
  </code></pre>