Tips for including a header with Apollo Client in a React Native app

In my React Native application, here's how I set up the Apollo client with an upload link:

My goal is to include a header with a token value that will be sent with every request. However, I've had trouble finding an example specifically for React Native.

import { AsyncStorage } from 'react-native'
import { ApolloClient } from 'apollo-client'
import { createUploadLink } from 'apollo-upload-client'
import { InMemoryCache } from 'apollo-cache-inmemory'

const client = new ApolloClient({
  link: createUploadLink({
    uri: 'http://localhost:3000/graphql'
  }),
  cache: new InMemoryCache()
})

The following code snippet shows how I want to send the token value in the header:

const token = await AsyncStorage.getItem('auth.token')

Update

I'm trying to figure out how to insert the token from AsyncStorage into the header. The use of await won't work here because it's not within an async function:

const token = await AsyncStorage.getItem('auth.token') // await can't work here

// Initialize apollo client
const client = new ApolloClient({
  link: createUploadLink({
    uri: 'http://localhost:3000/graphql',
    headers: {
      authorization: token
    }
  }),
  cache: new InMemoryCache()
})

// Wrap apollo provider
const withProvider = (Component, client) => {
  return class extends React.Component {
    render () {
      return (
        <ApolloProvider client={client}>
          <Component {...this.props} client={client} />
        </ApolloProvider>
      )
    }
  }
}

export default async () => {
  Navigation.registerComponent('MainScreen', () => withProvider(MainScreen, client))

  Navigation.startSingleScreenApp({
    screen: {
      screen: 'MainScreen'
    }
  })
}

Answer №1

createUploadLink comes with a headers attribute that corresponds to the headers attribute of createHttpLink.

headers: an object containing values to be included as headers in the request.

Example

const token = await AsyncStorage.getItem('auth.token')

const client = new ApolloClient({
  link: createUploadLink({
    uri: 'http://localhost:3000/graphql',
    headers: {
      "Some-Custom-Header": token
    }
  }),
  cache: new InMemoryCache()
})

UPDATE

const getToken = async () => {
  const token = await AsyncStorage.getItem('auth.token')
  return token
}
const token = getToken()
// Initialize apollo client
const client = new ApolloClient({
  link: createUploadLink({
    uri: 'http://localhost:3000/graphql',
    headers: {
      authorization: token
    }
  }),
  cache: new InMemoryCache()
})
// Add apollo provider wrapper
const withProvider = (Component, client) => {
  return class extends React.Component {
    render () {
      return (
        <ApolloProvider client={client}>
          <Component {...this.props} client={client} />
        </ApolloProvider>
      )
    }
  }
}

export default async () => {
  Navigation.registerComponent('MainScreen', () => withProvider(MainScreen, client))

  Navigation.startSingleScreenApp({
    screen: {
      screen: 'MainScreen'
    }
  })
}

Answer №2

I recently started using apollo boost, and my approach was as follows:

import ApolloClient from 'apollo-boost';

const client = new ApolloClient({
  uri: 'http://localhost:3000/graphql',
  request: async (operation) => {
    const token = await AsyncStorage.getItem('token');
    operation.setContext({
      headers: {
        authorization: token
      }
    });
  }
}

Answer №3

Implementing a callback with getItem also proves to be effective

import { ApolloClient, HttpLink, ApolloLink, InMemoryCache } from 'apollo-boost'

const httpLink = new HttpLink({
  uri: 'http://localhost:4000/graphql',
})

const authLink = new ApolloLink((operation, forward) => {
  AsyncStorage.getItem('AuthToken').then(token => {
    operation.setContext({
      headers: {
        authorization: token ? `Bearer ${token}` : '',
      },
    })
  })
  return forward(operation)
})

const apolloClient = new ApolloClient({
  cache: new InMemoryCache(),
  link: authLink.concat(httpLink),
})

Answer №4

In June 2021, I devised a solution in the form of a gist file that can be utilized with both AsyncStorage and React-Redux. This solution eliminates the need for additional dependencies like apollo-boost, especially if you are already using apollo-client. Give it a try and hopefully, it will work seamlessly for you.

Just a heads up:

This implementation is specifically designed to help you set up token or authentication headers on your apoll-client graphql requests.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Trouble Arising in Showing the "X" Symbol upon Initial Click in Tic-Tac-Toe Match

Description: I'm currently developing a tic-tac-toe game, and I've run into an interesting issue. When I click on any box for the first time, the "X" symbol doesn't show up. However, it works fine after the initial click. Problem Details: ...

eslint is designed to not handle multiple package.json files

There are two package.json files in my project root folder └ app ---- /public └ /styles └ /src └ package.json └ eslintrc.json └ webpack.config.js └ server - /something └ /something ...

Using multiple GET methods on a single route in Express and Sequelize can lead to conflicts

I've created a simple product CRUD application with routes to search for products by ID and by name. However, when I send a request to http://localhost:4000/products?name=pen, the routes conflict with each other and I'm unable to retrieve the pro ...

Generate an interactive pie chart with visually appealing animations using jQuery, without any actual data

My task involves creating a pie chart to visually display different categories. However, the challenge is that the chart does not contain any data, ruling out options like Google charts or other data-driven chart makers. As a solution, I have turned the pi ...

Is there a way to verify in AngularJS whether ng-model contains a string or a numerical value?

In my Angular application, I have written a JavaScript function that checks if the value of a text field is undefined or empty, and it is working properly. $scope.checkNumber = function(user_answer){ if(user_answer == undefined){ return false; } } My ...

What are some ways to ensure that text can adapt to the size of a

I am looking to create dynamic text that adjusts based on the size of its parent container. As the parent container's size changes, I want the text to automatically adjust accordingly. Specifically, I want the text in a widget to resize when the widg ...

Updating the model of a Vuejs single file component (.vue) within the <script> tag

Discovering the world of vuejs, I set out to create a basic single file component for testing purposes. This component's main task is to showcase a boolean and a button that toggles the boolean value. It also listens for a "customEvent" which trigger ...

Tips on transferring information from a component to an instance in Vue

My goal is to retrieve data from a component and transfer it to a variable within my root Vue instance. Vue Instance Configuration: new Vue({ el: '#root', data: { searchResultObject: '' }, methods: { // ...

Utilize the onChangeText function in React Native to filter out each individual value within a nested array

I currently have an array with nested children in it, where the children can range from one to multiple values. I am working on implementing a local filter within my component. Whenever a user types anything into the textInput, the application will display ...

Shopify module is throwing an error stating that React is not defined

I wanted to create my first Shopify module, but I encountered an error in my application page on the shop while using React. Here is my index.js code: import {Page} from "@shopify/polaris"; import {ResourcePicker} from "@shopify/app-bridge- ...

Transferring image Buffer over API for uploading to IPFS network

My attempt to upload an image to IPFS involves the following steps: I start by uploading the image from my web UI, converting it to a buffer in my Angular component. The next step is to send it via a put/post request (using HttpClient) to my NodeJS Expres ...

Guide to rendering a div class conditionally in a Razor page depending on a variable?

How can I dynamically render a div with different classes in Angular based on a condition? <div class="@(myArray.length>0 ? "col-md-8" : "col-md-12" )"> I'm trying to achieve that if the length of myArray is greater than 0, then it should h ...

What advantages do binary shifts offer in enums?

What do you think about this code snippet? /** * Bitmask of states */ export const enum ViewState { FirstCheck = 1 << 0, // result is 1 ChecksEnabled = 1 << 1, // result is 2 Errored = 1 << 2, // result is 4 ...

Implement a function to trigger and refresh components in various Vuejs2 instances simultaneously

I currently have index.html with two Vue instances in different files: <!DOCTYPE html> <html lang="en"> <body> <div id="appOne"> </div> <div id="appTwo"> </div> </body> </html ...

What is the best way to prevent a window from opening when the required form fields are left blank?

Currently, I have a submit button on my form that triggers a jQuery function to open a window based on the user's selection. However, I only want the window to open if all the necessary fields are filled out. I have the existing code for this function ...

Can you explain how the interactive notification on stackoverflow is generated when you are responding to a question and someone posts a new answer?

Have you ever been in a situation where you're writing an answer to a question, but then someone else posts their response and a popup appears notifying you of the new answer? I'm curious about how that whole process works. It seems like the answ ...

Dispatching actions in `componentDidMount` is restricted in Redux

Update at the bottom of post I've created a React container component called AppContainer, which checks if the user is authenticated. If the user is authenticated, it renders the app's routes, header, and content. If not, it displays a Login com ...

Tips for organizing cards into a grid layout using react native

I am looking to organize the cards in a grid view layout. I have experimented with various grid view components, but I am struggling to navigate to each item within the data of npm install react-native-super-grid. That's why I am considering creating ...

Function modifies global variable

What could be causing the global variable to change when using the function write_ACK_ONLY()? I'm passing the array rxUartBuffer to write_ACK_ONLY() as data = new Array(20), but upon checking the Log Output, it seems that the function is also modifyin ...

Leveraging Prisma Client alongside Supabase Edge Functions

I encounter an issue when trying to integrate the generated @prisma/client with Supabase Edge functions. Running npx prisma generate places the client in the default location within my node_modules folder, inaccessible for edge function usage. To resolve t ...