GraphQL Return Query Result as an Array - reactjs

I have been following the React-Apollo and Node.js GraphQL Tutorials on https://www.howtographql.com/ and was able to get a demo up and running.
What I would like to do now is return the result of my query as an array.
My schema.graphql file looks like this:
type Query{
pullTickets (where: TicketWhereInput): [Ticket!]!
}
And the resolver looks like:
const resolvers = {
Query: {
pullTickets: (root, args, context, info,) => {
return context.db.query.tickets({}, info)
}
}
}
What I have tried so far is:
import React, { Component } from 'react';
import Query from "react-apollo/Query";
import gql from "graphql-tag";
const GET_TICKETS = gql`
query getTickets($startDate: DateTime!, $endDate: DateTime!) {
pullTickets (where: {
AND:[{DateCloseDate_gt: $startDate}, {DateCloseDate_lt: $endDate}]})
{
id
}
}
`;
export default function GetTickets ( startDate, endDate ) {
var temp = [];
<Query query={GET_TICKETS} variables={{ startDate, endDate }} >
{({ loading, error, data }) => {
if (loading) return 'Loading...';
if (error) return `Error!: ${error}`;
// This doesn't seem to do anything
temp = data.pullTickets
}}
</Query>
// temp is showing up as "undefined" in the console
console.log(temp);
return temp
}
I should be getting a list of Tickets but I am getting undefined.

How to use client.query or client.mutation without using jsx
I had the same issue, I wanted to use query without using any jsx, the solution is to use ApolloClient, at some point in your app you will use ApolloProvider which u will need to give it an instance of ApolloClient as a prop, all u have to do is export that client and u can then use it anywhere else not only in the ApolloProvider.
Here is an example
initApollo.js
this is where Apollo client is initialized.
import { ApolloClient } from 'apollo-client';
.
.
.
initApolloClient ({ uri }) => {
.
.
.
return new ApolloClient({
link,
cache,
});
}
export default initApolloClient
useClientWithoutJsx.js
import initApollo from './initApollo';
client = initApollo({ uri: 'http://localhost:4000' });
client.query(({query: SOME_QUERY, variables: {id: 2}) => {
// return data
})
does this answers your question ?

Related

Graphql urql refetch every n seconds

Im using Typescript, React- and graphql with the urql client library.
My Query looks something like this:
query objectId($id: Int!) {
object(id: $id) {
id
name
__typename
}
}
This is how I call the query:
const [{ data }] = useObjectIdQuery({ variables: { id }, pause: !id });
Question:
How can i refetch every n seconds without reloading the page?
My backend reads JSON files and they update consistently.
Now I have looked into the documentation here, and also on a bunch of Stackoverflow and no-name sites.
Thank you.
I found out that the documentation provides a function for that. I built myself a hook to use it in the whole project for any query. Just becareful with the query parameter, it has to be the already build graphql DocumentNode as parameter.
You can import them like this for each Query:
import { ObjecIdDocument } from "../../graphql";
The graphql path may be different in your case.
This is the full Hook:
import { useEffect } from "react";
import { useQuery } from "urql";
import { DocumentNode } from "graphql";
const useRefreshingQuery = (variables: object, query: DocumentNode, delayInSec: number, pause: boolean) => {
const [result, reexecuteQuery] = useQuery({
query: query,
variables: variables,
pause: pause,
});
useEffect(() => {
if (result.fetching) {
return;
}
const timerId = setTimeout(() => {
reexecuteQuery({ requestPolicy: "network-only" });
}, delayInSec * 1000);
return () => clearTimeout(timerId);
}, [result.fetching, reexecuteQuery, variables]);
return result;
};
export default useRefreshingQuery;
You can use the Hook like this:
import { ObjecIdDocument } from "../../graphql";
const result = useRefreshingQuery({ id: UID }, ObjectIdDocument, 10, !UID);

Apollo Client: Can't put ReactHook after Conditional, but React Hook needs data available only after conditional?

Order of Operations issues it seems.
Can't use a React Hook after a Conditional as I get this error:
Error: Rendered more hooks than during previous render
This React Hook is 3rd party and can't change it. This React Hook needs data that is only available after the conditional...so I get another error of data not defined
Ok, how about declare a new variable (empty array) to put in 3rd party React hook before conditional? Then after conditional reassign with data that shows up. Doesn't work either... as I get error that it is using the same key...well because the 3rd party hook is getting an empty array variable first. What do I do?
import { libraryHook } from '3rd party'
import { useQuery } from '#apollo/client'
const myComponent = () => {
const {loading, error, data } = useQuery(MY_QUERY, { variables: {someVariable: fromDatabase}
const { 3rdpartyVariable } = libraryHook(data);
// Hook needs to be above conditional so I don't get error,
//but data only available after conditional.
if (loading) return <div>Loading...</div>;
if (error) return <div>{error.message}</div>;
console.log(data);
return(
<div>
{data}
</div>
)
}
export default myComponent;```
There is another hook called useLazyQuery that can be used in this case, it provides you a function that can be called to execute your query. This is how you can do it
import { gql, useLazyQuery } from "#apollo/client";
const GET_GREETING = gql`
query GetGreeting($language: String!) {
greeting(language: $language) {
message
}
}
`;
function Hello() {
const [loadGreeting, { called, loading, data }] = useLazyQuery(
GET_GREETING,
{ variables: { language: "english" } }
);
if (called && loading) return <p>Loading ...</p>
if (!called) {
return <button onClick={() => loadGreeting()}>Load greeting</button>
}
return <h1>Hello {data.greeting.message}!</h1>;
}
Refer Docs

Getting data Gatsby.js and contentful

I have pages in contenful with different URLs. Now I'm getting all data from all pages, but I need to get different data for different URL. I'm tryin to filter it, but get error. So How I can check if url='something' I need query it ?
import React from "react";
import { StaticQuery, graphql } from "gatsby";
import ArticleMfo from "../components/articleMfo";
const Products = () => (
<StaticQuery
query={graphql`
query MyQuery {
allContentfulAllPages(filter: {link: {eq: $MYURL}}) {
edges {
node {
mfo {
__typename
... on ContentfulBank {
id
text
limit
rate
term
link
logo {
title
file {
url
}
}
}
}
}
}
}
}
`}
render={data => (
<Container className="container">
{data.allContentfulAllPages.edges.map(({ node }, i) => (
<div>
{node.mfo.map(mfos => (
<ArticleMfo key={mfos.id} content={mfos} />
))}
</div>
))}
</Container>
)}
/>
);
export default Products
Static query (hence the name) does not accept variables. As you can see from the Static Query docs:
StaticQuery does not accept variables (hence the name “static”), but
can be used in any component, including pages
If you want to filter it, you will need to use a page query and pass the variable name (MYURL) via context on each page. In that case, you'll need to move your query to gatsby-node.js and, on every page creation, pass the variable through context to make it available to use as a filter. Something like:
const path = require("path")
exports.createPages = async ({ graphql, actions, reporter }) => {
const { createPage } = actions
const result = await graphql(
`
{
allMarkdownRemark(limit: 1000) {
edges {
node {
frontmatter {
path
}
}
}
}
}
`
)
// Handle errors
if (result.errors) {
reporter.panicOnBuild(`Error while running GraphQL query.`)
return
}
const blogPostTemplate = path.resolve(`src/templates/blog-post.js`)
result.data.allMarkdownRemark.edges.forEach(({ node }) => {
const path = node.frontmatter.path
createPage({
path,
component: blogPostTemplate,
// In your blog post template's graphql query, you can use pagePath
// as a GraphQL variable to query for data from the markdown file.
context: {
pagePath: path,
},
})
})
}
Note: Replace the query above and the resolvers for your data.
With the snippet above, every page created from the GraphQL query will have the path available (as pagePath) through context to filter, adapt it to your needs.

React GraphQL - How to return the results of a Query component as an object to use in React context

I have a Query component which gets the information of the a user who has logged in. The query itself works but I am having trouble returning the results of the query as an object which I then want to pass to React.createContext()
I am using Apollo client to make my Query component in my React application.
The following is an example of my current code:
function getUser() {
return (
<Query query={query.USER_INFO}>
{({ loading, error, data }) => {
if (loading) return <div>Loading</div>;
if (error) return <div>error</div>;
const userInfo = {
name: data.user.name,
age: data.user.age,
}
}}
</Query>
);
}
//need userInfo object to go here
export const UserContext = React.createContext(userInfo);
How can I get the return of the Query to then use in React.createContext? The reason I want to do it this way is to avoid rewriting this Query in every component where I want info of the user who has logged in.
To be honest, to me it seems like you're just missing a return statement:
function getUser() {
return (
{({ loading, error, data }) => {
if (loading) return Loading;
if (error) return error;
const userInfo = {
name: data.user.name,
age: data.user.age,
}
return userInfo // ----- this here
}}
</Query>
);
}
//need userInfo object to go here
export const UserContext = React.createContext(userInfo);
but i didn't test it out and haven't taken this approach - give it a go see, if it helps

React + GraphQL: dataArray.map is not a function

I Just started learning graphQL and Apollo.
Below is the sample client side code using Apollo client.
I am providing data from nodemon express server.
console.log(data) shows the output from the server.
However i was trying to display the query result using the apollo client but i was unbale to do so. I am stuck in this , any help will be appreciated.
import React from "react"
import { Query } from "react-apollo";
import gql from "graphql-tag";
export const ExchangeRates = () => (
<Query
query={gql`
{
counterparty {
name
}
}
`}
>
{({ loading, error, data }) => {
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
console.log(data) // Works fine as expected
var a= data.map(x=>{
return x.name
})
return <div> Data {a}</div> // stuck here ..how to display data
}}
</Query>
);
The following codes gives an error and says
TypeError: data.map is not a function
However the console.log(data) works fine and the following output:-
Your are doing wrong here... your array is inside data.counterparty...
try this
var a= data.counterparty.map(x=>{
return x.name
})

Resources