use graphql query and mutation in same file - reactjs

const QUERIES = gql`
query {
getGrades {
grade_info
id
}
getSubjects {
id
subject_info
}
getSchools {
school_name
id
}
}
`;
const MUTATIONS = gql`
mutation {
createTeacher(
first_name: ${firstName}
last_name: ${lastName}
phone: "${number}
email: ${email}
subjectRef: ["6287323efe0b204eee241cc5"]
gradeRef: ["62872b8b0023e0dcc9c5a703"]
schoolRef: "62ab59edde044d104f10e5a9"
) {
id
first_name
last_name
phone
email
email_verified
approved
number_verified
}
}
`;
const { loading, error, data } = useQuery(QUERIES);
const [mutateFunction, { data, loading, error }] = useMutation(MUTATIONS);
Here is my graphql query using in react .
But my data variable conflicting in query and mutation
How to handle the situation ?
Please take a look .
If am changing data to something else it is not working.

You are using a destructuring assignment in order to extract the fields data, error, loading from the response of useQuery and useMutation.
The destructuring assingment operator allows renaming the variables (please find better variable names than I used as an example ;-) )
Example:
const { loading: loadingQueries, error: errorQueries, data: dataQueries } = useQuery(QUERIES);
//use
console.log(loadingQueries);
The same can be applied for useMutation.

Related

Passing ID in GraphQL query not returning data

so i'm trying to use Apollo GraphQL with React to get specific product data by its ID, but it seems to be returning undefined. I read the Apollo docs and researched, so I'm not sure what I'm doing wrong. Also, I'm able to return data from other queries that don't require an ID (like all products, for instance). Would greatly appreciate some help!
Query
export const PRODUCT = gql`
query GetProduct($itemID: String!) {
product(id: $itemID) {
id
name
inStock
gallery
description
category
attributes {
id
name
type
items {
displayValue
value
}
}
prices {
currency {
label
symbol
}
}
brand
}
}
`;
This is where I try to return data using the ID, but to no avail:
let myID = "ps-5";
const { productLoading, productError, productData } = useQuery(PRODUCT, {
variables: { itemID: myID },
});
useEffect(() => {
if (productData) {
console.log("data: " + productData) // logs nothing. "Undefined" when if statement is removed
}
}, [])
It looks like the React client for Apollo uses the same API for useQuery as for Vue (with which I'm more familiar), in which case it should be used like this:
useQuery(PRODUCT, { itemID: myID })
(not { variables : { itemID : myID }})
I would have expected the backend to return an error though, because $itemID is declared as non-nullable.
It seems that you are destructing the object that useQuery() returns with the wrong object keys.
// instead of
const { productLoading, productError, productData } = '...'
// you can either use the regular keys as variables
const { loading, error, data } = '...'
// or assign aliases (useful when you use more queries on the same page)
// this way you can use the same variables as in your example
const { loading:productLoading, error:productError, data:productData } = '...'

GraphQL on component load, Query will sometimes return populated properties as null

I am using graphQl with react with apollo client and mongoose. Sometimes when I click on a component. rand om data will return from this useQuery as null.
// must define novel as a state to use useEffect correctly
const [novel, setNovel] = useState({});
const { loading, data } = useQuery(GET_NOVEL, {
variables: { _id: novelId }
});
// use effect ensures that all novel data is completely loaded
// before rendering the SingleNovel page
useEffect(() => {
console.log(data?.novel);
// if there's data to be stored
if (data) {
setNovel(data.novel)
}
}, [data, loading, novel]);
export const GET_NOVEL = gql`
query getNovel($_id: ID!) {
novel(_id: $_id) {
_id
title
description
penName
user {
_id
username
email
}
favorites{
_id
}
createdAt
reviews {
_id
reviewText
rating
createdAt
user{
_id
username
}
}
chapterCount
reviewCount
}
}
`
Specifically, the novel.user.username and reviews.rating property come back as null. On reload of the page however, the data seems to populate the fields normally.
How can I fix this?
Heres the resolver
novel: async (parent, { _id }) => {
// returns single novel from the novel id given
const novel = await Novel.findOne({ _id })
.populate('user')
// populate the reviews for the novel but also populate
// the info within the reviews of the user who made each review.
.populate({
path: 'reviews',
populate: {path: 'user'}
})
.exec();
console.log(novel)
return novel;
},

Nested graphql query

I am pretty new with graphql , I don't know how to apply this filter.
following is schema
const GET_TICKETS = gql`
query Ticket($filter: String) {
tickets(filter: $filter) {
id
title
firstname
lastname
gender
contactnumber
email
address
pincode
location
emergency_type
priority
descriptionof_assistance
date_created
status
work_items {
id
status
service
volunteers {
volunteer_id
volunteer_name
status_of_acceptance
}
}
}
}
`;
I want to fetch all tickets where workitems contain given volunteer
fetch tickets where volunteer in workitems.volunteers ....something like this
When you use useQuery There is an optional second parameter or useLazyQuery on the function trigger.
Example from the official documentation.
useQuery
const { loading, error, data } = useQuery(GET_DOG_PHOTO, {
variables: { breed },
});
So on your case it should be
const { loading, error, data } = useQuery(GET_TICKETS, {
variables: { filter: "the filter value" },
});
and on useLazyQuery will look like this:
const [getTickets, { loading, error, data }] = useLazyQuery(GET_TICKETS);
//..... somewhere else
getTickets({variables: {filter: "filter value"}})
reference: https://www.apollographql.com/docs/react/data/queries/

Apollo Client is not reading variables passed in using useQuery hook

Having a weird issue passing variables into the useQuery hook.
The query:
const GET_USER_BY_ID= gql`
query($id: ID!) {
getUser(id: $id) {
id
fullName
role
}
}
`;
Calling the query:
const DisplayUser: React.FC<{ id: string }> = ({ id }) => {
const { data, error } = useQuery(GET_USER_BY_ID, {
variables: { id },
});
return <div>{JSON.stringify({ data, error })}</div>;
};
Rendering the component:
<DisplayUser id="5e404fa72b819d1410a3164c" />
This yields the error:
"Argument \"id\" of required type \"ID!\" was provided the variable \"$id\" which was not provided a runtime value."
Calling the query from GraphQL Playground returns the expected result:
{
"data": {
"getUser": {
"id": "5e404fa72b819d1410a3164c",
"fullName": "Test 1",
"role": "USER"
}
}
}
And calling the query without a variable but instead hard-coding the id:
const GET_USER_BY_ID = gql`
query {
getUser(id: "5e404fa72b819d1410a3164c") {
id
fullName
role
}
}
`;
const DisplayUser: React.FC = () => {
const { data, error } = useQuery(GET_USER_BY_ID);
return <div>{JSON.stringify({ data, error })}</div>;
};
Also returns the expected result.
I have also attempted to test a similar query that takes firstName: String! as a parameter which also yields an error saying that the variable was not provided a runtime value. This query also works as expected when hard-coding a value in the query string.
This project was started today and uses "apollo-boost": "^0.4.7", "graphql": "^14.6.0", and "react-apollo": "^3.1.3".
[Solved]
In reading through the stack trace I noticed the issue was referencing graphql-query-complexity which I was using for validationRules. I removed the validation rules and now everything works! Granted I don't have validation at the moment but at least I can work from here. Thanks to everyone who took the time to respond!
I had also ran into a similar issue and was not really sure what was happening.
There seems to be similar problem reported here - https://github.com/apollographql/graphql-tools/issues/824
We have 2 options to fix the issue.
- First one is a simple fix, where in you don't make the ID mandatory when it takes only a single parameter ( which is not an object )
const GET_USER_BY_ID= gql`
query($id: ID) {
Second option is to use an object as a parameter instead of a primitive. I went ahead with this and it seemed to work fine for me even though I made the object and the property inside to be required.
// On the client
const GET_USER_BY_ID= gql`
query($input: GetUserInput!) {
getUser(input: $input) {
id
fullName
role
}
}`;
const { data, error } = useQuery(GET_USER_BY_ID, {
variables: { input: { id }},
});
// In the server, define the input type
input GetUserInput {
id: ID!
}
Try
const { data, error } = useQuery(GET_USER_BY_ID, { id });

Passing ID as correct variable type in GraphQL Mutate function

I'm trying to edit an item using GraphQL by passing in arguments using this.props.mutate. I'm getting following error... Error: GraphQL error: Variable $id of required type ID! was not provided. Hence, the problem lies in me passing the wrong ID type to the mutate function. Anyone know how to pass the ID type as the correct type to the mutate function? or can I cast the ID type from string to the correct type to pass as variable to the mutate function? Thank you
i'm using local component state to hold the values to prefill a form in case you are wondering why I am using local state
import UPDATE_CHAT_MUTATIONS from '../graphql/mutations/updateChat';
class EditChat extends React.Component {
state = {
text: '',
id: ''
}
componentWillMount() {
this._onEditLoad()
}
_onEditLoad = () => {
const chat = this.props.navigation.state.params;
this.setState({ text: chat.text, id: chat._id })
}
_onChangeText = text => this.setState({ text });
_onEditPress = async () => {
const { id, text } = this.state;
await this.props.mutate({
variables: {
_id: id,
text
}
});
Keyboard.dismiss();
this.props.navigation.goBack(null);
}
i managed to get it to work! I made an error on the graphql mutations on the client side. Below is the code that works!! Hope this will help those who face the same issue. Cheers
import { gql } from 'react-apollo';
export default gql`
mutation updateChat($_id: ID!, $text: String!) {
updateChat(_id: $_id, text: $text) {
text
_id
updatedAt
}
}
`;

Resources