apollo-client icon indicating copy to clipboard operation
apollo-client copied to clipboard

`fetchPolicy: 'network-only'` receives no broadcasts under certain conditions

Open jsindos opened this issue 2 years ago • 2 comments

Issue Description

I have the following schema:

  type Query {
    products: [Product]
  }

  type Product {
    id: Int
    isLiked: Boolean
  }

  type Mutation {
    toggleProductIsLiked(id: Int, isLiked: Boolean): Product
  }

I am calling this schema as follows:

  const { data: { products } = { products: [] } } = useQuery(Products, {
    fetchPolicy: 'network-only',
    notifyOnNetworkStatusChange: 'notifyOnNetworkStatusChange'
  })

  const [toggleProductIsLikedMutation] = useMutation(ToggleProductIsLiked)

  const toggleIsLiked = async (id, isLiked) => {
    await toggleProductIsLikedMutation({
      variables: {
        id,
        isLiked
      },
      optimisticResponse: {
        toggleProductIsLiked: {
          __typename: 'Product',
          id,
          isLiked: !isLiked
        }
      }
    })
  }

The server is inverting the boolean value of isLiked:

  Mutation: {
    toggleProductIsLiked (root, args) {
      const { id, isLiked } = args
      return { id, isLiked: !isLiked }
    }
  }

useQuery(Products) is not getting the broadcasted result of toggleProductIsLikedMutation (isLiked flipping) when both of the following conditions are true:

  1. The fetchPolicy is set to network-only
  2. optimisticResponse is set

I am wondering if this behaviour is intended, and if there is any easy way to circumvent this behaviour without having to switch either of these things off?

Link to Reproduction

https://github.com/jsindos/NetworkOnlyReceivesNoBroadcasts

Reproduction Steps

No response

jsindos avatar Apr 24 '23 06:04 jsindos

Hi @jsindos,

thank you for reporting this. This is definitely not intended, and most likely a bug. We'll investigate this.

phryneas avatar Apr 26 '23 14:04 phryneas

Hey @jsindos 👋

Thanks for your patience on this issue! We've done some investigating and unfortunately it appears that the behavior you're seeing was the original intended behavior of a network-only fetch policy. Unfortunately it seems that not all of the library followed through on the original intention of the fetch policy, hence why you're seeing this "under certain conditions". I think this issue highlights the fact that we really need to focus on clarifying how a fetch policy affects the lifetime of a query.

After more discussion, we've determined that we don't think we have a great way to address this issue that wouldn't otherwise break existing behavior in the library, or at the very least, introduce inconsistency. Either way we go with this would be introducing a breaking change somewhere. We have no way of determining how many apps rely on the existing behavior as a feature of the library.

Unfortunately this means we'll need to leave this "broken" for now. We'd like to address fetch policies more broadly in a future major so we can really ensure their behavior is standard across all of the client and clarify the intention behind them. I'll leave this issue open for this reason.

For now, our recommendation is to use the nextFetchPolicy option with cache-first so that updates will rerender as you expect.

jerelmiller avatar Jul 08 '24 16:07 jerelmiller