-
Notifications
You must be signed in to change notification settings - Fork 731
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to perform cache manipulation after mutations / subscriptions? #357
Comments
You can use ApolloStore's WithinReadWriteTansaction stuff to modify the contents of the cache. There is not good documentation right now, but you can probably find what you need by reading tests. See ReadWriteStoreTests.swift. |
Hey @ashiemke! Thanks for the response. I definitely noticed the methods within the ApolloStore class that allow you to read and write queries, but I believe the issue is the fact that the |
Hey, just wanted to give an update here seeing my last comment is coming up on being a month old. I explored this topic quite extensively, even adding the Apollo iOS xcodeproj as a direct dependency of my app so I could debug it properly. First of all, I tested my theory by making the client store and other needed class members public so I could modify the store from my app correctly. However, upon copying the code verbatim from ReadWriteFromStoreTests, I noticed that the code tested there doesn't actually work as expected. It works for the tests because you are defining the cache schema within the test, statically, however, in a production app it seems to read the cache differently. This leads to a number of cache misses, causing the promise surrounding the cache write calls to fail. I'll explain a little more. So this is the call I was trying to make, a simple call updating the cache with a new message in a conversation after it is sent: let mutationInput = TextMessageInput(
text: textMessage,
conversationId: conversationID
)
let mutation = NewTextMessageMutation(input: mutationInput)
_ = apollo.perform(mutation: mutation) { (result, error) in
let msg = result?.data?.createTextMessage
let resultMap = msg?.resultMap
let message = msg?.fragments.textMessage
let query = ConversationQuery(id: conversationID)
do {
try apollo.store.withinReadWriteTransaction { transaction in
try transaction.update(
query: query
) { (data: inout ConversationQuery.Data) in
data.conversation?.messages?.insert(
ConversationQuery.Data.Conversation.Message( id: "999",
content: "test",
authorId: "4",
created: "20180901",
unread: false),
at: 0
)
}
}
} catch {
print("error")
}
} Yet the cache never updated. So I started to investigate the cache
So I dug deeper, and found that during the executor call chain, a function is called to retrieve fields (keys) inside an object (the cache). Following this through, I found that a JSON
It's trying to read the cache key from what appears to be the raw response of the mutation coming back from the server, which is why there's a cache miss. I updated the This was all I could uncover. I unfortunately don't have a ton of context on how the Apollo cache actually works, but this at least seems to be an underlying bug from what I can tell. Hopefully someone has a little more knowledge about what a fix might be? |
I'm interested with this feature as well. Hope anyone from apollo can help? |
Given that there's no ability to selectively remove (#362) or update cache entries I have to fall back to either completely clear the cache or execute certain queries with |
@Nickersoft Since #413 Got merged, can this issue now be closed? |
Since I haven't heard back in a couple weeks and #413 has been merged, I'm going to close this one out. Please feel free to reopen if it's still causing issues in newer versions! |
As a longtime user of Apollo's React / JS-based client, I know that a pretty common practice when performing mutations or subscriptions to update Apollo's internal cache so any updates can propagate throughout the rest of the app. This practice is heavily described in the docs on optimistic UI responses and subscriptions. For example, in JS this might look like:
I know questions about the cache have been asked here before, but there do not seem to be any examples, recommendations, docs, etc. on how you might be able to achieve this kind of manipulation.
I use ReSwift in my app and have considered passing in a custom store object, and am wondering if this might be the only way. Without ReSwift, any modification I make to an external cache object won't affect the client cache because Apollo copies the init parameter to an internal variable.
This seems like a pretty instrumental concept in the Apollo ecosystem... am I missing something?
The text was updated successfully, but these errors were encountered: