So create graphene query and works on GraphiQL, I'm trying to connect it to react using apollo client but I keep getting error.
On Django the error is
graphql.error.located_error.GraphQLLocatedError: 'AnonymousUser' object is not iterable
on React the error is Error! 'AnonymousUser' object is not iterable
As you can see here, it's working on GrahiQL
Here is my setup
URL
path("graphql/", csrf_exempt(GraphQLView.as_view(graphiql=True))),
SETTINGS
CORS_ORIGIN_WHITELIST = [
"http://localhost:3000",
"http://127.0.0.1:3000"
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
....
]
INSTALLED_APPS = [
.....
"graphene_django",
'corsheaders',
]
INDEX.JS
import React from "react";
import { ApolloProvider, ApolloClient, InMemoryCache } from "#apollo/client";
const client = new ApolloClient({
uri: "http://localhost:8000/graphql/",
cache: new InMemoryCache(),
});
ReactDOM.render(
<ApolloProvider client={client}>
<App />
</ApolloProvider>,
document.getElementById("root")
);
In EMPLOYEELIST.JS
import { useQuery, gql } from "#apollo/client";
const EMP = gql`
query getEmployees {
allEmployees {
id
fullName
isActive
hourlyRate
slug
paystubData
}
}
`;
export const ListEmployee = () => {
const { loading, error, data } = useQuery(EMP);
if (loading) return "Loading...";
if (error) return `Error! ${error.message}`;
const [records, setRecords] = useState(data.allEmployees);
...
return(
.....)
I tested the react component with localstorage first and everything was fine there too, now bring the two together, I'm getting this error. I don't know what I'm missing here really.
Any help will be appreciated.
Related
I'm trying to get more familiar with graphql using react-apollo and I'm stuck for a while now.
I just want to query movies by name from a gql server, but no luck so far. My problem is that when I make the request I get an error that says:
POST https://tmdb.sandbox.zoosh.ie/dev/grphql 400
However I want to make a GET request. I tried to specify the request method in the apollo client, but no luck either.
index.js
import React from "react";
import ReactDOM from "react-dom/client";
import {
ApolloClient,
InMemoryCache,
ApolloProvider,
HttpLink,
} from "#apollo/client";
import "./index.css";
import App from "./App";
const client = new ApolloClient({
cache: new InMemoryCache(),
link: new HttpLink({
uri: "https://tmdb.sandbox.zoosh.ie/dev/grphql",
method: "GET",
}),
connectToDevTools: true,
});
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<ApolloProvider client={client}>
<App />
</ApolloProvider>
</React.StrictMode>
);
MovieList.js
import React from "react";
import { useQuery, gql } from "#apollo/client";
const SEARCH_MOVIES = gql`
query SearchMovies($movieTitle: String!) {
movies(query: $movieTitle) {
id
name
score
genres {
name
}
overview
releaseDate
}
}
`;
const MovieList = () => {
const { loading, error, data } = useQuery(SEARCH_MOVIES, {
variables: {
movieTitle: "fight club",
},
});
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
return (
<>
<div>MovieList</div>
<ol>
{data.movies.map((movie) => (
<li key={movie.id}>{movie.name}</li>
))}
</ol>
</>
);
};
export default MovieList;
Now I would appriciate, if someone could help me out what the problem might be, because my eyes can't see it. I searched all over the internet, but didn't find any usable resource regarding the topic.
Thanks for the replies in advance!:)
You can use useGETForQueries as constructor options.
docs
const client = new ApolloClient({
cache: new InMemoryCache(),
link: new HttpLink({
uri: "https://tmdb.sandbox.zoosh.ie/dev/grphql",
useGETForQueries: true
}),
connectToDevTools: true,
});
I need some pro advice here because I am going a little crazy. I am trying to create an graphql client combining Apollo and AppSync. I've done this approach before, but it is not working in another project I've just created. My situation is the following:
It seems that the client is connecting to my AppSync server (it is returning the __typename in the data), but It is not returning anything else. This is an example of the client use and the response I am getting:
const response = client
.query({
query: gql`
query MyQuery {
listSys_users {
items {
email
name
active
user_id
}
}
}
`,
})
.then(console.log);
I've tried to call the server making a POST request with axios and it works perfectly fine:
const axiosWrapper = () => {
const defaultOptions = {
baseURL: envConfig.graphQLUrl,
headers: { 'x-api-key': envConfig.graphQLApiKey },
};
const instance = axios.create(defaultOptions);
return instance;
};
axiosWrapper.post('', {
query: `
query MyQuery {
listSys_users {
items {
email
name
active
user_id
}
}
}
`,
}).then(console.log);
Now that You know the situation I will share my attempts on this:
Right know I have something like this:
The client.js:
import { ApolloLink } from 'apollo-link';
import { HttpLink } from 'apollo-link-http';
import ApolloClient from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { createAuthLink } from 'aws-appsync-auth-link';
import config from './configs/env';
const { graphQLUrl, region, graphQLApiKey } = config;
const auth = {
type: 'API_KEY',
apiKey: graphQLApiKey,
// jwtToken: async () => (await Auth.currentSession()).getAccessToken().getJwtToken(),
};
const authMiddleware = new ApolloLink((operation, forward) => {
// add the authorization to the headers
operation.setContext(({ headers = {} }) => ({
headers: {
...headers,
'x-api-key': 'MY_API_KEY',
accept: 'application/json, text/plain, */*',
'content-type': 'application/json;charset=UTF-8',
},
}));
return forward(operation);
});
const client = new ApolloClient({
link: ApolloLink.from([authMiddleware, new HttpLink({ uri: graphQLUrl })]),
cache: new InMemoryCache(),
});
export default client;
The App.js:
import 'react-app-polyfill/ie11';
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { ApolloProvider } from 'react-apollo';
import { Provider } from 'react-redux';
import App from './App';
import store from './store/reducers/rootReducer';
import './helpers/Translation/i18n';
import Login from './pages/Login';
import client from './client';
ReactDOM.render(
<ApolloProvider client={client}>
<BrowserRouter>
<Provider store={store}>
<Login>
<App />
</Login>
</Provider>
</BrowserRouter>
</ApolloProvider>,
document.getElementById('root')
);
Package.json:
"apollo-cache-inmemory": "^1.6.6",
"apollo-client": "^2.6.10",
"apollo-link": "^1.2.14",
"apollo-link-http": "^1.5.17",
"aws-amplify": "^3.3.27",
"aws-amplify-react-native": "^4.3.2",
"aws-appsync": "^4.1.4",
"aws-appsync-react": "^4.0.10",
"graphql": "^15.6.1",
"graphql-tag": "^2.12.5",
In this case the response is the same, it is connecting but it returns null in the items.
Yes, I know, I should use the creatAuthLink from aws-appsync-auth-link. Thats my second attempt.
My second attempt was using createAuthLink, but when I tried to use it It throw this error:
./node_modules/aws-appsync-auth-link/lib/auth-link.js
Module not found: Can't resolve '#apollo/client/core' in '/Users/VIU/GEOACTIO/smart-pockets/smart-pockets-react/node_modules/aws-appsync-auth-link/lib'
So I ended up installing and using the #apollo dependencies:
client.js:
import { ApolloClient, ApolloLink, HttpLink, InMemoryCache } from '#apollo/client';
import { createAuthLink } from 'aws-appsync-auth-link';
import config from './configs/env';
const { graphQLUrl, region, graphQLApiKey } = config;
const auth = {
type: 'API_KEY',
apiKey: graphQLApiKey
};
const client = new ApolloClient({
link: ApolloLink.from([
createAuthLink({ auth, region, url: graphQLUrl }),
new HttpLink({ uri: graphQLUrl }),
]),
cache: new InMemoryCache(),
});
export default client;
package.json:
"#apollo/client": "^3.4.16",
...all the same
Still getting the same response.. I won't bother You with more attempts. I've tried all the possible combination between these and more apollo / graphql / appsync dependencies and the outcome is always the same: either I get the null response with the __typename or I get a dependencies error.
NOTE: I've noticed that when using axios, the lambda attached to that resolver fires up as it should, but when using another approach, the lambda doesn't fire up, so obviously it won't return any data.
I know it is a long post but I am trying to explain the best I can my situation. And I can't create a sandbox code because I don't want to expose the API credentials.. Any ideas of what I am doing wrong?
Thanks in advance!!
I'm new to using GraphQL in React and have been moving a project from a REST API to a new GraphQL one. As part of this, I wanted to setup mock data to work on the application independent of the GQL API being completed. I've spent a bunch of time trying to follow the Apollo and GraphQL Tools docs but no matter what, I can't seem to get the mock resolvers to work properly. For context, I am using this in a NextJS/React app, and here's a minimum example of what I'm trying to do:
Setup App.js
import React from 'react';
import ApolloClient from 'apollo-client';
import { ApolloProvider } from 'react-apollo';
import { SchemaLink } from 'apollo-link-schema';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { makeExecutableSchema } from '#graphql-tools/schema';
import { addMocksToSchema } from '#graphql-tools/mock';
export default function App() {
const schema = makeExecutableSchema({typeDefs:`
type Query {
getPerson: Person!
}
type Person {
name: String!
}
`});
const mocks = {
Query: () => ({
getPerson: () => ({
name: () => "Name"
})
})
}
addMocksToSchema({ mocks, schema });
const link = new SchemaLink({ schema });
const client = new ApolloClient({
link,
cache: new InMemoryCache(),
connectToDevTools: true
});
return (
<ApolloProvider client={client}>
<Person />
</ApolloProvider>
)
}
Person.js
import React from 'react';
import { useQuery } from '#apollo/react-hooks';
import gql from 'graphql-tag';
export default function Person() {
const { loading, error, data } = useQuery(gql`
query PersonQuery {
getPerson {
name
}
}
`, {
errorPolicy: 'all'
});
console.log(data);
if (loading) return "Loading...";
if (error) console.log(error);
return (
<h1>{data.getPerson.name}<h1>
)
}
Looking at the console.log(error) result yields the error Cannot return null for non-nullable field Query.getPerson and making it a nullable field just returns { getPerson: null } of course. I've tried returning the resolver results as objects vs functions. Logging within the resolvers shows the Query part is being executed but nothing nested within that.
Am I setting something up incorrectly? I also tried not passing in custom mocks as suggested should be possible based on the graphql-tools docs, but to no avail. I also saw this issue from the apollo hooks GitHub that said the newest version of hooks broke the usage of addMocksToSchema, so I tried using the suggested 3.1.3 version but again no luck. Any help would be greatly appreciated!
You need to provide the mock to the client, not the plain schema.
const schemaWithMocks = addMocksToSchema({
schema,
mocks: {},
preserveResolvers: false,
});
const client = new ApolloClient({
// link: new SchemaLink({ schema }); < -- REPLACE THIS
link: (new SchemaLink({ schema: schemaWithMocks }) as unknown) as ApolloLink, // https://github.com/apollographql/apollo-link/issues/1258
cache: new InMemoryCache(),
connectToDevTools: true,
});
Now console.log(data) prints
{"getPerson": {"__typename": "Person", "name": "Name"}} 🎉
In my apps, I am using following NPM modules to play with Strapi, GraphQL and Next.js:
react-apollo
next-apollo
graphql
gql
recompose
In the next step, I am creating Apollo config file, example below:
import { HttpLink } from "apollo-link-http";
import { withData } from "next-apollo";
const config = {
link: new HttpLink({
uri: "http://localhost:1337/graphql",
})
};
export default withData(config);
and then inside a class component, I am using a static method getInitialProps() to fetch data from the Strapi via GraphQL query.
Everything is fine but maybe there is another, better way via React hooks or any other?
I found one more nice hook solution for Next.js and GraphQL.
I want to share it with you. Let's start.
Note: I assume that you have Next.js application already installed. If not please follow this guide.
To build this solution we need:
#apollo/react-hooks
apollo-cache-inmemory
apollo-client
apollo-link-http
graphql
graphql-tag
isomorphic-unfetch
next-with-apollo
1. run npm command:
npm install --save #apollo/react-hooks apollo-cache-inmemory apollo-client apollo-link-http graphql graphql-tag isomorphic-unfetch next-with-apollo
2. create Appolo config file, eg. in folder ./config and call it appollo.js. File code below:
import { ApolloClient } from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";
import withApollo from "next-with-apollo";
import { createHttpLink } from "apollo-link-http";
import fetch from "isomorphic-unfetch";
const GRAPHQL_URL = process.env.BACKEND_URL || "https://api.graphql.url";
const link = createHttpLink({
fetch,
uri: GRAPHQL_URL
});
export default withApollo(
({ initialState }) =>
new ApolloClient({
link: link,
cache: new InMemoryCache()
.restore(initialState || {})
})
);
3. create _app.js file (kind of wrapper) in ./pages folder with below code:
import React from "react";
import Head from "next/head";
import { ApolloProvider } from "#apollo/react-hooks";
import withData from "../config/apollo";
const App = ({ Component, pageProps, apollo }) => {
return (
<ApolloProvider client={apollo}>
<Head>
<title>App Title</title>
</Head>
<Component {...pageProps} />
</ApolloProvider>
)
};
export default withData(App);
4. create reusable query component, eg. ./components/query.js
import React from "react";
import { useQuery } from "#apollo/react-hooks";
const Query = ({ children, query, id }) => {
const { data, loading, error } = useQuery(query, {
variables: { id: id }
});
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {JSON.stringify(error)}</p>;
return children({ data });
};
export default Query;
5. create a component for our data fetched via GraphQL
import React from "react";
import Query from "../components/query";
import GRAPHQL_TEST_QUERY from "../queries/test-query";
const Example = () => {
return (
<div>
<Query query={GRAPHQL_TEST_QUERY} id={null}>
{({ data: { graphqlData } }) => {
return (
<div>
{graphqlData.map((fetchedItem, i) => {
return (
<div key={fetchedItem.id}>
{fetchedItem.name}
</div>
);
})}
</div>
);
}}
</Query>
</div>
);
};
export default Example;
6. create our GraphQL query inside ./queries/test-query. Note: I assume that we have access to our example data and properties id and name via GraphQL
import gql from "graphql-tag";
const GRAPHQL_TEST_QUERY = gql`
query graphQLData {
exampleTypeOfData {
id
name
}
}
`;
export default GRAPHQL_TEST_QUERY;
7. to display our result create index.js file (homepage) in ./pages folder with below code:
import Example from './components/example';
const Index = () => <div><Example /></div>
export default Index;
That's all.. enjoy and extend this solution as you want..
I have found one more interestng solution with using apollo-server-micro and lodash
Quick guide:
create Next.js app (example name: next-app) and install required packages
npm i apollo-server-micro lodash
create required files in you Next.js app (next-app)
/next-app/pages/api/graphql/index.js
/next-app/pages/api/graphql/resolvers.js
/next-app/pages/api/graphql/typeDefs.js
add code to index.js
import { ApolloServer } from 'apollo-server-micro';
import resolvers from './resolvers';
import typeDefs from './TypeDef';
const apolloServer = new ApolloServer({
typeDefs,
resolvers,
});
export const config = {
api: {
bodyParser: false
}
};
export default apolloServer.createHandler({ path: '/api/graphql' });
add code to typeDefs.js
import { gql } from 'apollo-server-micro';
const typeDefs = gql`
type User {
id: Int!
name: String!
age: Int
active: Boolean!
}
type Query {
getUser(id: Int): User
}
`;
export default typeDefs;
add code to resolvers.js
import lodash from 'lodash/collection';
const users = [
{ id: 1, name: 'Mario', age: 38, active: true },
{ id: 2, name: 'Luigi', age: 40, active: true},
{ id: 3, name: 'Wario', age: 36, active: false }
];
const resolvers = {
Query: {
getUser: (_, { id }) => {
return lodash.find(users, { id });
}
}
};
export default resolvers;
test your Next.js app (next-app) by running below command and checking graphql URL http://localhost:3000/api/graphql
npm run dev
I'm creating an apollo react application. I want apollo to manage my local state. I want to structure my local state so not all scalar values are at the top level.
This is my configuration:
import React from 'react'
import ReactDOM from 'react-dom'
import ApolloClient from 'apollo-boost'
import gql from 'graphql-tag'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloProvider, Query } from 'react-apollo'
const defaults = {
author: null
}
const resolvers = {
Query: {
author() {
return { id: 1 }
}
}
}
const typedefs = gql(`
type Query {
author: Author
}
type Author {
id: Int
}
`)
const apolloClient = new ApolloClient({
clientState: {
defaults,
resolvers,
typedefs
},
cache: new InMemoryCache()
});
ReactDOM.render(
<ApolloProvider client={ apolloClient }>
<Query query={ gql`{ author #client }` }>
{ ({ data }) => console.log(data.author) || null }
</Query>
</ApolloProvider>,
document.getElementById('app')
)
Then this app logs undefined. I.e., the query { author #client { id }} returns undefined in data.author.
It must be noted that when I set the type of author as Int, default value as 1, and I do the query { author #client }, the app correctly logs 1.
How can I have some structure in my local state with Apollo?
These are my relevant dependencies:
apollo-cache "^1.1.20"
apollo-cache-inmemory "^1.3.8"
apollo-client "^2.4.5"
apollo-link "^1.0.6"
apollo-link-error "^1.0.3"
apollo-link-http "^1.3.1"
apollo-link-state "^0.4.0"
graphql-tag "^2.4.2"
Solved:
Apparently I had to add __typename: 'Author' to the defaults author this way:
const defaults = {
author: {
__typename: 'Author'
}
}