Apollo read multiple values from cache - apollo-client

I'm looking for a way to read the value from cache for Apollo. On the page of Apollo, it only show the way to retrieve one as follow:
With readQuery
const READ_TODO = gql`
query ReadTodo($id: ID!) {
todo(id: $id) {
id
text
completed
}
}
`;
// Fetch the cached to-do item with ID 5
const { todo } = client.readQuery({
query: READ_TODO,
variables: { // Provide any required variables here. Variables of mismatched types will return `null`.
id: 5,
},
});
or with readFragment
const todo = client.readFragment({
id: 'Todo:5', // The value of the to-do item's cache ID
fragment: gql`
fragment MyTodo on Todo {
id
text
completed
}
`,
});
However, I can't select more than 1 todo at a time in both of them. I will have an array of IDs I'm not sure how many values will be in it. What is an excellent approach to this problem?

Related

graphQL useQuery refetch

I have multiple queries combined in one request.
Later, when user make some changes I need to refetch only one of those combined queries with new variables.
I added directives #include on those queries that I don't need to fetch again.
The problem is, on refetch, my cache is overwritten with new data from that single query.
How can I persist my cache, and only update it on refetch with new data and not overwrite it?
const { loading, error, data, refetch } = useQuery(GET_DATA, {
fetchPolicy: 'network-only',
variables: {
something,
includeSummary: true,
},
});
refetch(
{
...variables,
includeSummary: false,
}
);
export const GET_DATA = gql`
query Something(
$args: DataInput
$includeSummary: Boolean!
) {
summary #include(if: $includeSummary) {
.......
}
dynamicData(args: $args) {
........
}
}
`;

Apollo-client: Add item to array in cache

Suppose I have the following GraphQL types:
type User {
id: String!
posts: [Post!]!
}
type Post {
id: String!
text: String,
}
And here is a mutation that returns the updated post:
mutation addNewPost(
$userId: String!
$text: String!
) {
addNewPost(userId: $userId, text: $text) {
id
text
}
}
After running this mutation my cache contains a new entry of a post. How do I add it to the user's posts array? I have tried cache.writeQuery and cache.modify but I cannot figure it out.
We do push the item into array inside the update function, which is one of the options of useMutation.
I'm writing the whole mutation so that you can get the idea 💡, let have a look at example:
By Update function:
const [createPost, { data, loading, error }] = useMutation(CREATE_POST, {
update(cache, response) {
// Here we write the update
// Step 1: Read/Fetch the data 👈
const data = client.readQuery({
query: FETCH_POSTS_QUERY,
});
// Step 2: Update the cache by immutable way 👈
client.writeQuery({
query: FETCH_POSTS_QUERY,
data: {
getPosts: [response.data.createPost, ...data.getPosts],
},
});
},
variables: formValues,
});
By refetchQueries:
That's really shortcut 🔥 way to update the cache, by using DocumentNode object parsed with the gql function
const [createPost, { data, loading, error }] = useMutation(CREATE_POST, {
refetchQueries: [ 👈
FETCH_POSTS_QUERY
'fetchPosts`' // OR Query name
],
variables: formValues,
});
You're going to want to directly write to the Apollo cache in order to update the other entities that your mutation has modified.
Have a look at the docs https://www.apollographql.com/docs/react/data/mutations/#making-all-other-cache-updates here for specifics (you're going to want to use cache.modify and cache.writeFragment)

Gatsby - making a dynamic query to Contentful

I'm working on a simple e-commerce based on Gatsby and Contentful.
One of my pages is CartPage.
So I'm trying to make a query to Contenful to get the necessary info about my products, so I want to pass a list of product ids that are in the user's cart.
Here's my component and query:
export interface CartPageProps {
data: {
products: GQL.ContentfulProductConnection;
};
}
const CartPage = ({ data }: CartPageProps) => {
const mockCart = [1, 2];
console.log(data);
return (
<IndexLayout>
<Page>
//
// Layout goes here
//
</Page>
</IndexLayout>
)
}
export default CartPage;
const pageQuery = graphql`
query ProductsInCart($mockCart: [Int], $lang: String) {
products: allContentfulProduct(filter: { idProduct: { in: [1, 2] }, node_locale: { eq: "en" } }) {
edges {
node {
id
idProduct
price
title
quantity
photo {
resize(height: 200, width: 200) {
src
}
}
slug
}
}
}
}
`;
Now all I get on a console.log(data) is undefined.
If I do the same query but with useStaticQuery with all the data hardcoded - I get the desired data. But useStaticQuery doesn't accept variables.
Am I doing something wrong here? How can I pass variables to the query and put my data to the props?
Gatsby uses GraphQL at build-time and not for live sites. as said here So it's not intended for making GraphQL queries on the go.

Query variables not being passed down from vue component in apollo

I have a simple query which takes in an ID parameter, but it is not working. It says "TypeError: Cannot read property 'taskId' of undefined" . So I think it does not recognize the 'this' keyword for some reason.
Please take a look:
Apollo query from frontend component:
getCommentsByTask: {
query: GET_COMMENTS_BY_TASK,
variables: {
taskId: this.taskId
},
result({ data }) {
this.getComments = data;
console.log("data", data);
}
}
Defined the query in frontend:
query GET_COMMENTS_BY_TASK($taskId: ID!) {
getCommentsByTask(taskId: $taskId) {
id
parentId
ownerId
text
}
}
Resolver in server:
async getCommentsByTask (_, {taskId}, context) {
const userId = getUserId(context)
const user = await User.findById(userId)
if (!user) return
const comments = await Comment.findById(taskId)
return comments
}
Schema:
type Query {
getCommentsByTask(taskId: ID!): [Comment]
}
Assuming that's a smart query, variables should be a (regular, non-arrow) function if you need access to this.

Pass ID from React to Apollo to find correct result?

Im using React with Apollo (Apollo Client v2). I have group query which needs to return a single group.
This code is working but I've hard coded HARD-CODED-ID. How can I instead pass the ID as a string from the React component?
In my React component:
const groupQuery = gql`
query Group {
group {
_id
name
}
}
`;
export default graphql(groupQuery, {
props: ({ data }) => ({ ...data }),
})(GroupPage);
My resolver:
Query: {
groups() {
return Groups.find().fetch();
},
group() {
return Groups.findOne('HARD-CODED-ID');
},
}
There's three things that you'll need to do:
1.) If you haven't already, modify the schema on your server so that your query accepts the id as an input, for example:
type Query {
#other queries
group(id: ID!): Group
}
2.) Modify your resolver so that it handles the passed-in id. Assuming you're using graphql-tools:
group(root, { id }) {
return Groups.findOne(id); // did you mean something like findOne({id}) ?
},
3.) Modify your client-side code. Typically, you'll make the id a prop you pass in to your component, and then use that as a variable in your request.
const groupQuery = gql`
query Group($id: ID!) {
group(id: $id) {
_id
name
}
}
`;
// assuming that the component prop is called groupId
export default graphql(groupQuery, {
options: ({ groupId }) => ({
variables: { id: groupId },
}),
})(GroupPage);
Instead of an object, options can be a function, in which case it's passed the component's props as its first parameter. You can then use those props to define the variables your query will use. You can read more about using variables with Apollo client here and here.

Resources