-
Notifications
You must be signed in to change notification settings - Fork 653
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
Consider updating the docs for isLast on ApolloResponse if they are not up to date #6129
Comments
Thanks! I've removed the example about I've left the caveat about false negatives for now - I'm a bit reluctant to remove it since it still makes sense that some producers may not have a way to know when an item is the last one, even if I can't think of specific examples of that. |
That's great, thanks for addressing this! When we mention that some producers may not know when the item is the last one, is that for other interceptors that users of this library may be creating themselves, or something that even if you can't think of a real example, may still potentiall happen using any of the CacheFirst, CacheOnly, NetworkOnly, NetworkFirst and CacheAndNetwork fetch policies? |
User defined interceptors is certainly a case. This should never happen due to the regular fetch policies. I was also thinking of something like |
Sounds very good, thanks for the clarification. And I agree that the docs can keep this open-ended for the reasons who describe. |
FWIW, I'm thinking we should probably deprecate AFAIK, the only usage is for watchers to subscribe to the store before emiting the last item of the initial query. So that callers get a guarantee that whatever change they do after they have received it will be seen by the watcher. It's still a bit kludgy and I'm hoping we can find a way to restructure this without requiring an @StylianosGakis did you have a specific need for |
Hehe I do in fact have one, let me try and explain. It stems from a discussion we've had in kotlinlang slack before. And I discussed this with my colleague to see what would make the most sense for how we typically use this API. So our use case was to be able to use CacheAndNetwork, without having to on the call site know that you are using CacheAndNetwork. And by that I mean that with this policy, in a flow you'd get back things in this order:
This on the UI would be reflected like this:
What we want to experience instead is:
By skipping the intermediate error emission. This was materialized in this code here: Now how is this related to CacheAndNetwork? With CacheOnly for example, where isLast is true, we know we are not getting a new emission anyway, so in that case we do in fact want to show the error screen, since there's nothing "saving us" from there, it is the final thing they will see on that screen. I hope this makes sense, and if you got ideas on how to achieve this without |
Initially I thought it would be fine to emit both things, and on the call site where one does know which policy they set, they could be careful to ignore such cache misses manually, but after a discussion with my colleague we decided against it since it felt like more room for human error than we would like to have for a thing which we do so often in the entire codebase. |
Would something like this work? fun <D : Operation.Data> ApolloCall<D>.safeFlow(): Flow<Either<ApolloOperationError, D>> {
return flow {
var hasEmitted = false
var errorResponse: ApolloResponse<D>? = null
toFlow().collect {
if (it.exception != null) {
// Some errors may be followed by valid responses.
// In that case, wait for the next response to come instead.
errorResponse = it
} else {
hasEmitted = true
emit(it)
}
}
if (!hasEmitted && errorResponse != null){
// Flow has terminated without a valid response, emit the error one if it exists.
emit(errorResponse)
}
}.map { either { parseResponse(it) } }
} It's slightly different in meaning but I think it achieves the same thing in practice. I'd argue it's also maybe more correct, i.e. not only about |
In the CacheAndNetwork scenario, won't this do exactly this?
Which is what I wanted to avoid here? Did you by any chance mean that the
Should be after the closing bracket of the inner |
Ah yeah that must be what you mean. What can I say, this looks much much much better than what I did. It also guards against scenarios where isLast may be implemented wrongly, due to perhaps some interceptor that we add in the future somehow. I think you just won yourself a |
Yup, that was 100% the intent, sorry! I just edited the codeblock |
This is exactly what's making me itchy about |
Yup, I can totally understand, as I was trying to make use of it, it was tricky both to see how it's used inside the library itself, how it's set or not set, and then this doc threw me off a bit too. Overall not relying on it makes me much more confident indeed! |
After feedback by Martin here apollographql/apollo-kotlin#6129 Replace the implementation which relied on the isLast to a much more robust implementation which should cover what the previous implementation did plus more.
Documentation has been updated, so closing this for now. |
Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Kotlin usage and allow us to serve you better. |
Description
I am reading the docs over here
apollo-kotlin/libraries/apollo-api/src/commonMain/kotlin/com/apollographql/apollo/api/ApolloResponse.kt
Lines 94 to 96 in 19fc22b
And I am trying to understand if the text
For an example, the CacheAndNetwork fetch policy doesn't emit the network item if it fails.
remains to be true in version 4.x too.Looking inside the interceptor itself
apollo-kotlin/libraries/apollo-normalized-cache/src/commonMain/kotlin/com/apollographql/apollo/cache/normalized/FetchPolicyInterceptors.kt
Lines 111 to 130 in 19fc22b
I see that the chain simply proceeds as-is after we try to hit the cache first. How is the network request ignored in this case?
There was a brief discussion about this here https://slack-chats.kotlinlang.org/t/22727664/with-4-x-error-handling-i-wanted-to-see-if-it-s-possible-to-#ff570c24-3ca2-487e-92c1-56fe05dfc1e6 too, and I hope this helps.
The text was updated successfully, but these errors were encountered: