How to pass Unique Id in Graphql query - reactjs

I'm trying to pass a unique id to a GraphQL query to get all data against the id. But when I print the console it shows undefined. Note that if I want to see all posts the then it becomes successful by another query.
in my query.js file I have written the below query:
export const Unique_Post_Query= gql`
query SampleQueries($id: ID!) {
post(_id: $id) {
id
data {
title
body {
text
}
}
}
}`;
and the below code from another file where I'm trying to see the result of the query:
const id='e42fd2b5-b84a-4417-afd2-36cdbaa204dd';
const { data , error,loading} = useQuery(Unique_Post_Query, { variables: {id ,}, });
//const { error, loading, data } = useQuery(PROFILE_QUERY);
console.log('yourrrrr f data',data);

Please check below reference
const id='e42fd2b5-b84a-4417-afd2-36cdbaa204dd';
const { loading, data } = useQuery(Unique_Post_Query, {
variables: { id: id},
});
useEffect(() => {
if (data && data?.post) {
console.log("data: ", data?.post);
}
}, [data]);

Related

Query data doesn't update after successful apollo cache write

I have a query on my App.js:
import { gql } from 'apollo-boost';
const ALL_ITEMS_QUERY = gql`
query ALL_ITEMS_QUERY {
challenges {
id
title
}
goals {
id
title
completed
createdAt
updatedAt
steps {
id
completed
title
}
}
}
`;
And i am looking to write a simple deleteGoal mutation:
const DeleteWrapper = (props) => {
const [deleteGoal, { data }] = useMutation(DELETE_ITEM_MUTATION, {
update(cache, payload) {
const data = cache.readQuery({ query: ALL_ITEMS_QUERY });
data.goals = data.goals.filter(
(goal) => goal.id !== payload.data.deleteGoal.id
);
cache.writeQuery({ query: ALL_ITEMS_QUERY, data });
},
});
}
The function returns the modified array correctly, but the item never disappears from the frontend list. I have a hunch that this is related to querying multiple categories at once (goals and challenges, rather than goals only).
Even though the cache seems to be modified correclty, why does the item never disappear, why does the re-render never happen?
After some trial and error I found out that I have to lay out the exact data object to the writeQuery function. I don't really understand why, since the challenges object was left untouched after the query. I have not been able to make this work otherwise.
const DeleteWrapper = (props) => {
const [deleteGoal] = useMutation(DELETE_ITEM_MUTATION, {
update(cache, { data: { deleteGoal} }) {
const { goals, challenges } = cache.readQuery({ query: ALL_ITEMS_QUERY });
const newArr = goals.filter((goal) => goal.id !== deleteGoal.id);
cache.writeQuery({
query: ALL_ITEMS_QUERY,
data: { challenges, goals: newArr },
});
},
});
}

Return data from custom Hook calling a graphql query

I am new to graphql and react.. Here , I have following method,
export const useName = (isRequest: boolean) => {
const {
nav: { id, idme }
} = stores
if (buyingSession) {
const { data, loading,error}
= usegroup(id, {
fetchPolicy: 'cache-and-network'
})
} else {
const {data} = usesingle(idme)
}
return data;
}
//This function should return a string which will be in data object.But I am getting confused over here because its a query and it takes time so it returns undefined but when I checked in the network it gives response as well.
export const useme = (id: string) => {
return useQuery(GET_ME, {
fetchPolicy: "cache-first",
skip: !id,
variables: {
id: id
}
}
In another component , I am calling ,
const data = useName(true)
So, this is the call which actually calls the graphql query. Now , when I am getting data it gets undefined.
How do resolve this issue ?

Using fetchMore to fetch ALL data on component mount

I have a situation where I need to fetch e.g. all articles posted by a user when a component is mounted. To get a user's articles I am using the following query:
const GET_USER_ARTICLES = gql`
query getUserArticles($id: ID, $numArticles: Int!, $cursor: String) {
user(id: $id) {
id
articles(first: $numArticles, after: $cursor, orderBy: "-created", state: "enabled") #connection(key: "userArticles") {
edges {
node {
name
}
}
pageInfo {
endCursor
hasNextPage
}
}
}
}
`;
If there is a next page I want to keep fetching more articles until I have ALL of them. Up until now I haven't had the need to do anything like this (normally I have a button the user can click "Load more" to fetch more articles for example, but now need to fetch everything without a user interacting with anything), so I'm not sure what the best way to go about this is.
An example of the query in React:
const PAGE_SIZE = 10;
const { data, loading, fetchMore } = useQuery<UserArticlesData, UserArticlesVariables>(
GET_USER_ARTICLES,
{ variables: { id: userId, numArticles: PAGE_SIZE, cursor: null } },
);
I am a little lost how I can use the fetchMore to keep fetching until there aren't any more pages left, while also showing a loading state to the user. I'm also not sure this is the best way to go about this in the first place, so any suggestions are more than welcome!
If the API does not limit the page size, you could just provide an arbitrarily large number as the page size to get the remaining results. Assuming the page size can only be so big, though, you can do something like this:
const { data, loading, fetchMore } = useQuery(GET_USER_ARTICLES, {
variables: { id: userId, numArticles: PAGE_SIZE, cursor: null },
notifyOnNetworkStatusChange: true,
})
const fetchRest = async () => {
const { user: { articles: { pageInfo } } } = data
const updateQuery = (prev, { fetchMoreResult }) => {
// Merge the fetchMoreResult and return the combined result
}
let hasNextPage = pageInfo.hasNextPage
let cursor = pageInfo. endCursor
while (hasNextPage) {
const { data } = await fetchMore({
variables: { id: userId, numArticles: PAGE_SIZE, cursor },
updateQuery,
})
const { user: { articles: { pageInfo } } } = data
hasNextPage = pageInfo.hasNextPage
cursor = pageInfo. endCursor
}
}
By setting notifyOnNetworkStatusChange to true, loading will be updated whenever fetchMore is doing any fetching. Then we just loop until hasNextPage is called. fetchMore returns a Promise that resolves to the query result, so we can use the query response outside the updateQuery function.
Note that this is a rough example -- you might actually want to keep track of loading state yourself, for example. If your API has rate limiting, your logic should account for that as well. However hopefully this gives you a good starting point.
Edit:
If you need to get all the articles initially, I wouldn't use useQuery and fetchMore at all. The easiest workaround would be to manage the data and loading state yourself and utilize client.query instead.
const client = useApolloClient()
const [data, setData] = useState()
const [loading, setLoading] = useState(true)
const fetchAll = async () => {
let hasNextPage = true
let cursor = null
let allResults = null
while (hasNextPage) {
const { data } = await client.query(GET_USER_ARTICLES, {
variables: { id: userId, numArticles: PAGE_SIZE, cursor },
})
// merge data with allResults
hasNextPage = pageInfo.hasNextPage
cursor = pageInfo. endCursor
}
setLoading(false)
setData(allResults)
}
useEffect(() => {
fetchAll()
}, [])

React / Graphql / Apollo, Not refetch data after update states and change routes

I have a graphql query that shows me a list of users, when I update the list with a mutation, the state change well, but when I change my route and I come back to the old one, it return the old state.I have to do a hard refresh on my browser to have the new list.
This is my query :
export const group = (id) => {
const data = Client.query({
query: gql`
query group($id: Int) {
group(_id: $id) {
_id
name
lat
lng
is_private
creation_date
}
}
})
This is my component :
async componentWillMount() {
try {
var data = await group(632);
var result = data.data.group[0];
this.setState({
group: result
});
} catch (e) {
console.log(e);
}
}
updateGroup = async() => {
try {
var data = await groupUpdate(501, 632, {
name: this.state.group.name,
is_private: this.state.group.is_private,
address: this.state.group.address,
creation_date: this.state.group.creation_date,
nbrEmployees: this.state.group.nbrEmployees
});
notifyUser(NOTIFY.success, "Done");
this.toggleInfo();
} catch (e) {
notifyUser(NOTIFY.error, "Error Serveur");
}
}
Any help please ?

Why are Results logging as undefined after a GraphQL Mutation?

In one of my components within a redux-form onSubmit, I have the following:
const result = await helloSignup(values);
console.log(result);
helloSignup is mutating the database as expected but the const result is currently be logged as undefined
Why?
My HOC/mutation helloSignup:
export const HELLO_SIGNUP_MUTATION = gql`
mutation (
$email: String!
$code: String!
) {
signup(authProvider: {
emailAndCode: {
email: $email
code: $code
}
}) {
token
user {
id
}
}
}
`;
export default graphql(
HELLO_SIGNUP_MUTATION,
{
props: ({ mutate }) => ({
emailAndCodeSignup: async (variables) => {
const { data } = await mutate({ variables });
const { token } = data.signup;
},
}),
}
);
Using GraphiQL, I can see that my graphql mutation, returns the desired results:
{
"data": {
"signup": {
"token": "xxx",
"user": {
"id": "16"
}
}
}
}
If GraphiQL is getting the desired results after mutating, why isn't the result being console logged above?
React-Apollo provides a HOC for client side queries and mutations called withApollo.
This signature is something like this:
withApollo(MyForm)
https://www.apollographql.com/docs/react/basics/setup.html#withApollo
which adds a prop of 'client' to the MyForm component. On form submission, you'd want to access this prop, and call the mutation from there. So in your form submit handler youd end up with something like this:
https://www.apollographql.com/docs/react/basics/mutations.html#basics
onSubmit() {
const { client } = this.props
const options = {} // your mutation options
// mutations ands queries return promises,
// so you must wait for their completion before accessing data
client.mutate(
HELLO_SIGNUP_MUTATION,
options
).then(({ data }) => (
console.log('got data', data);
)
}
}
Where data should be whats coming back from the API

Resources