Reputation: 4023
I have useQuery and useMutation from react-apollo-hooks back to back. I want to be able to use the returned values from useQuery as variables for useMutation. Currently, the values from useQuery isn't returned in time for the variables, causing the variables to be undefined.
const { data, error, loading } = useQuery(GET_POSTS, {
variables: {
id: props.match.params.id
}
})
const item = props.match.params.id
const owner = data.posts[0].author.id
const variables = { item , owner, startDate, endDate }
const bookItem = useMutation(CREATE_BOOKING_MUTATION, variables)
The variable data.posts[0].author.id
shows undefined. How do I make sure that the returned value is defined in time?
Upvotes: 3
Views: 8968
Reputation: 11
useMutation when the useQuery is completed like this:
const bookItem = useMutation(CREATE_BOOKING_MUTATION,{
variables:{//your variables},
// to refrech your query after you create mutation
refetchQueries: [
{
query: GET_POSTS,
awaitRefetchQueries: true,
},
]} );
const { data, error, loading } = useQuery(GET_POSTS, {
variables: {
id: props.match.params.id
},
//useMutation when the useQuery is completed
onCompleted: () => {
bookItem();
},
})
Upvotes: 0
Reputation: 326
I think you can pass the variables when you actually call the mutation instead, something like:
...
const bookItem = useMutation(CREATE_BOOKING_MUTATION)
...
if(!loading && !error && data) {
bookItem({
variables: {
owner: data.posts[0].author.id,
...
}
})
}
Upvotes: -1
Reputation: 8418
How do I make sure that the returned value is defined in time?
You can simply check condition after useQuery
block
Hooks can't be called conditionally.
Usual advice is to place condition in useEffect
:
const { data, error, loading } = useQuery(GET_POSTS, {
variables: {
id: props.match.params.id
}
})
const item = props.match.params.id
// data.posts can be undefined at start
const owner = loading ? null : data.posts[0].author.id
const variables = { item , owner, startDate, endDate }
const bookItem = useMutation(CREATE_BOOKING_MUTATION, variables)
useEffect(() => {
if(!loading) {
bookItem(); // called when data ready
}
})
Another option: useApolloClient
:
useQuery
to load data needed in mutation
const client = useApolloClient();
useEffect
- conditionally (!loading
or data
not empty) use client.mutate()
with fetched (in query) data as variables;Custom hook can be done with 3 parameters: (query, mutation, { mapDataToVariables })
Upvotes: 7