Remove an item from cache and from all lists (notify all watchers)

I want something like apolloStore.remove() but that it notifies all watchers and recreates all my lists without this item in it.

For example:
Post with ID 100 is in the topPosts List and mostLikedPosts List.
Now I delete it and it should get removed from all the lists that have the Post with ID 100 in it.

Hi :wave: !

Unfortunately this is not possible at the moment, you’ll have to update the list manually. The cache is a very simple key/value store that knows nothing about foreign keys or anything like that. We could think about supporting this but it’s a major undertaking so I wouldn’t hold my breath there.

You can follow this issue for updates

Okay thank you.
How can I add an item to the cached list?

"getUsersPosts" : [
CacheKey(Post:104)
CacheKey(Post:105)
CacheKey(Post:106)
CacheKey(Post:110)
]

When I add a Post item to that list and then like the post which triggers the watchers, the added post dissapears from the list again because the cached list still only has 4 items.
How can I add the item to this cached getUsersPosts list?

The easiest way is certainly to refetch your getUserPosts list avec a like but that comes at the price of an extra network request. If you want to handle everything locally, you’ll have to write the list using ApolloStore API:

val data = apolloStore.readOperation(query)
data = data.copy(
  getUsersPosts = data.getUsersPosts + CacheKey(Post = 111)
)
apolloStore.writeOperation(query, data)

I tried using the code you send but CacheKey complains:

val test = CacheKey(Post = 100)

None of the following functions can be called with the arguments supplied.

Then I tried it like this:

    override suspend fun addPost(post: Post) {
 
        var data = apolloStore.readOperation(GetUsersPostsQuery())
        val newPost = CacheKey(key = "Post:${post.id}")
        data = data.copy(getUsersPosts = data.getUsersPosts + newPost)
        apolloStore.writeOperation(GetUsersPostsQuery(), data)

    }

But here it complaints that there is a Type mismatch when trying to add the newPost to the data.gerUsersPosts list.

Type mismatch.
Required:
List<GetUsersPostsQuery.GetUsersPosts>
Found:
List<Any>

Right, good catch :+1: Sorry for missing this. Operations work at the Data level but CacheKey is at the Record level. Looking into it, I’ll post an update in a few minutes.

Can you try something like this?

    client.apolloStore.accessCache {
      val existingRecord = it.loadRecord(CacheKey.rootKey().key, CacheHeaders.NONE)!!

      val newUsers = (existingRecord.fields.get("users") as List<Any>) + CacheKey(key = "Post:${post.id}")
      val newRecord = Record(
          key = existingRecord.key,
          fields = existingRecord.fields + mapOf("users" to newUsers)
      )
      it.merge(newRecord, CacheHeaders.NONE)
    }

This assumes a query like this:

{
  users {
    id
    # ...
  }
}

Thank you, this is working.
Is there a way to choose the position for the merged item?
I want it at position 0, it.merge puts it at the end

Is there a way to choose the position for the merged item?

I believe yes! The list is newUsers so instead of appending, you can prepend:

// Replace 
val newUsers = (existingRecord.fields.get("users") as List<Any>) + CacheKey(key = "Post:${post.id}")

// With
val newUsers = listOf(CacheKey(key = "Post:${post.id}")) + (existingRecord.fields.get("users") as List<Any>)