← Back to all snippets
JAVASCRIPT

Querying a GraphQL API with Variables and Error Handling

Learn to execute client-side GraphQL queries with dynamic variables and robust error handling using JavaScript's Fetch API, managing both network and GraphQL-specific errors.

async function queryGraphQL(endpoint, query, variables = {}) {
  try {
    const response = await fetch(endpoint, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        // Add authorization headers if needed, e.g., 'Authorization': 'Bearer YOUR_TOKEN'
      },
      body: JSON.stringify({
        query,
        variables
      })
    });

    if (!response.ok) {
      // Handle HTTP errors (e.g., 401, 403, 500)
      const errorBody = await response.text();
      throw new Error(`HTTP error! Status: ${response.status}, Body: ${errorBody}`);
    }

    const result = await response.json();

    if (result.errors) {
      // Handle GraphQL errors (e.g., validation errors, resolver errors)
      console.error('GraphQL errors:', result.errors);
      // You might want to throw a specific error or process them differently
      throw new Error(`GraphQL query failed: ${result.errors.map(err => err.message).join(', ')}`);
    }

    return result.data;

  } catch (error) {
    console.error('Failed to query GraphQL API:', error);
    throw error; // Re-throw to allow caller to handle
  }
}

// --- Example Usage ---
const GRAPHQL_ENDPOINT = 'https://countries.trevorblades.com/'; // Public GraphQL API example

const GET_COUNTRY_DETAILS_QUERY = `
  query GetCountry($code: ID!) {
    country(code: $code) {
      name
      continent {
        name
      }
      languages {
        name
      }
    }
  }
`;

const GET_ALL_CONTINENTS_QUERY = `
  query {
    continents {
      code
      name
    }
  }
`;

// Example 1: Query with variables
queryGraphQL(GRAPHQL_ENDPOINT, GET_COUNTRY_DETAILS_QUERY, { code: 'US' })
  .then(data => {
    console.log('Country Details for US:', data);
  })
  .catch(error => {
    console.error('Error fetching country details:', error.message);
  });

// Example 2: Query without variables
queryGraphQL(GRAPHQL_ENDPOINT, GET_ALL_CONTINENTS_QUERY)
  .then(data => {
    console.log('All Continents:', data);
  })
  .catch(error => {
    console.error('Error fetching continents:', error.message);
  });

// Example 3: Simulating a bad query to see error handling (e.g., missing variable)
const BAD_QUERY = `
  query GetCountry($code: ID!) { 
    country(code: $code) { 
      nonExistentField 
    } 
  }
`;
queryGraphQL(GRAPHQL_ENDPOINT, BAD_QUERY, { code: 'US' })
  .then(data => {
    console.log('Bad Query result:', data); // This should not execute if errors are handled
  })
  .catch(error => {
    console.error('Error with bad query:', error.message);
  });
How it works: This JavaScript snippet demonstrates how to interact with a GraphQL API using the native `fetch` API, including passing dynamic variables and robust error handling. Unlike REST, GraphQL requests are typically `POST` requests where the `query` (and `mutation` or `subscription`) string and `variables` are sent in the JSON request body. This snippet covers checking for HTTP status codes for network-level issues and, importantly, inspecting the `errors` array within the GraphQL response itself for application-level errors (e.g., syntax errors, invalid fields, resolver failures). This dual-layer error checking ensures comprehensive handling of potential issues when consuming GraphQL services.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs