Reputation: 181
I'm learning how to make a react app using graphql and apollo.
At first, I was able to make a query that returned the posts from the server:
(in my app.js file)
<Query
query={gql`
{
feed {
id
title
}
}
`}
>
{({ loading, error, data }) => {
if (loading) return <p>...loading...</p>;
if (error) return <p>ERROR ! Try reloading</p>;
return data.feed.map(feed => (
<div key={feed.id}>{`Title: ${feed.title}`}</div>
));
}}
</Query>
);
It worked.
Then, I wanted to make queries and mutations that required authorization. Since the server requires headers I followed this recipe.
(in my index.js file)
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import ApolloClient from 'apollo-boost';
import { ApolloProvider } from 'react-apollo';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { createHttpLink } from 'apollo-link-http';
import { setContext } from 'apollo-link-context';
import registerServiceWorker from './registerServiceWorker';
import App from './App/App';
const GRAPHQL_API_URI = 'https://shopozor-server.herokuapp.com/';
const httpLink = createHttpLink({
uri: GRAPHQL_API_URI,
});
const authLink = setContext((_, { headers }) => {
// get the authentication token from local storage if it exists
const token = localStorage.getItem('token');
// return the headers to the context so httpLink can read them
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : "",
}
}
});
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});
ReactDOM.render(
<ApolloProvider client={client}>
<BrowserRouter>
<App />
</BrowserRouter>
</ApolloProvider>,
document.getElementById('root')
);
registerServiceWorker();
Then my previous query didn't work any more. I received an error payload instead of the posts. And an error message was written in the console:
[Network error]: SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
After debugging, I could know that the referred index.js file was located in the apollo-boost module, which starts with
"use strict"
Plus I found that the
createHttpLink({
uri: GRAPHQL_API_URI,
});
didn't use the link I gave it, but used an empty string instead.
Now i'm out of ideas. Can someone help me solving this problem ?
Thanks
Upvotes: 2
Views: 2324
Reputation: 181
A friend of mine figured out the problem. I'm using
import ApolloClient from 'apollo-boost';
instead of
import { ApolloClient } from 'apollo-client';
which are different packages with the same name. I had thought that apollo-boost was just a bundle using apollo-client, but no. If i make this tiny change, it works.
apollo-boost doesn't support all apollo features yet and, even if it gives a working client out of the box, I can't use it for everything. Have a look at this article.
Upvotes: 2
Reputation: 1280
You need to create the middleware first. Here is how I got it working
import { ApolloLink } from 'apollo-client-preset';
import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
const httpLink = new HttpLink({ uri: GRAPHQL_API_URI });
// Middleware to set the headers
const middlewareAuthLink = new ApolloLink((operation, forward) => {
const token = localStorage.getItem('token');
const authorizationHeader = token ? `Bearer ${token}` : null
operation.setContext({
headers: {
authorization: authorizationHeader,
},
});
return forward(operation);
});
const httpLinkWithAuthToken = middlewareAuthLink.concat(httpLink);
const client = new ApolloClient({
link: httpLinkWithAuthToken,
cache: new InMemoryCache(),
});
Upvotes: 0