I'm making an app for birdwatchers. When birdwatches see a bird, they record a sighting
. I have a query for a feed of all birdwatchers sightings:
import { gql } from "@apollo/client";
export const GET_SIGHTINGS = gql`
query Sightings($first: Int, $after: String) {
sightings(first: $first, after: $after) {
pageInfo {
endCursor
}
edges {
node {
id
location
note
seenAt
mapImage
images {
id
url
}
user {
id
name
emoji
}
bird {
id
commonName
}
}
}
}
}
`;
and this works great. Now i want to have a seperate feed for an individual birdwatchers sightings. (this query is working fine on the server):
import { gql } from "@apollo/client";
export const MY_SIGHTINGS = gql`
query MySightings($first: Int, $after: String, $userId: ID) {
mySightings: sightings(first: $first, after: $after, userId: $userId) @connection(key: "sightings", filter: ["userId"]) {
pageInfo {
endCursor
}
edges {
node {
id
location
note
seenAt
mapImage
images {
id
url
}
user {
id
name
emoji
}
bird {
id
commonName
}
}
}
}
}
`;
This works fine the first time the filtered query was run, however once the main feed component is rendered, the individual feed is now full of everyones sightings. How do I get the cache to descriminate between the two queries? The @connection
directive sounded like it would be the trick but apparently not
I'm using the Relay Specification for my API which means that my 'collections' are objects rather than arrays. This means I need to set a specific Type Policy to get pagination to work. This also unfortunately also breaks Apollos automatic handling of query params. Turns out I need to add userId
to the keyargs section of my type policy:
const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
sightings: {
keyArgs: ["userId"],
merge(existing, incoming, { args }) {
if (args && !args.after) {
return incoming;
}
if (!existing) {
return incoming;
}
const edges = unionBy("node.__ref", existing.edges, incoming.edges);
return { ...incoming, edges };
},
},
},
},
},
});