Consuming a GraphQL API using fetch - React Client - GeeksforGeeks

13 Dec, 2021
In this article, we will learn to develop a React application, which will fetch the data from a public GraphQL API using Fetch. We will use The Movie Database Wrapper ( TMDB ) API to fetch the shows available with name/keyword. You can find the API reference and source code links at the end of this article.
Before moving onto the development part, to initialize a simple react application you can follow the steps mentioned below: 
Step 1: Create React application.
npx create-react-app foldername
Step 2: Move into the project folder.
cd foldername
 
Step 3: Create a components folder and now Project Structure will look like:
Project Structure
This was basically the initial setup we require for our application. Now let us take a look at each of the components individually. Custom components reside in the components folder, with everything put together in the MainComponent.jsx, we will place this component inside App.js, which itself goes under the “root” DOM node, and everything inside this node will be managed by React DOM.
We are going to develop three components:
Main Component: Responsible for fetch operation and state changes in the application.
Search Bar: A search bar to get the user input for the show name/keyword.
ShowInfoCard: A reusable component to display the show information.
Step 4: In the MainComponent.jsx component, we have a state variable, data which will hold the response for the GraphQL API. 
const [data, setData] = useState(Object);
To fetch the information, we make a call to the apiEndpoint, but first let us break the GraphQL query apart, in general, to form a query, you must specify fields within fields until those fields resolve to actual data. In this way, you ask for specific fields on objects and get back exactly what you asked for. The structure of any GraphQL query looks like this: 
query {
    JSON objects to retrieve
}

With our query variable, we are trying to fetch all the shows available, using name/keyword, which is passed as an argument with $term. 
MainComponent.jsx (query part)
const apiEndpoint = "https://tmdb.apps.quintero.io/";const query = `    query FetchData($term: String!){        tv{            search(term:$term){              edges{                node{                    id                    originalName                }              }           }        }     }`;
To make the request using Fetch API, we send the GraphQL query and variables as a JSON object to the endpoint. GraphQL endpoint expects the body of the request to be a stringified JSON object that contains query and variables parameters. When the request is complete, the promise is resolved with the response object. This object is basically a generic placeholder for various response formats. response.json()  is used to extract the JSON object from the response, it returns a promise, which is again resolved and data is updated.MainComponent.jsx ( request part )
 
MainComponent.jsx (request part)
const getData = (term) => {       fetch(apiEndpoint, {           method: "POST",           headers: { "Content-Type": "application/json" },           body: JSON.stringify({               query,               variables: { term }           })       })           .then(res => res.json())           .then((data) => setData(data))           .catch(console.error); };
So finally our MainComponent.jsx looks like:
MainComponent.jsx
import React, { useState } from "react";import SearchBar from "./SearchBar";import ShowInfoCard from "./ShowInfoCard";  function Main() {    const [data, setData] = useState(Object);    const apiEndpoint = "https://tmdb.apps.quintero.io/";    const query = `        query FetchData($term: String!){            tv{                search(term:$term){                  edges{                    node{                        id                        originalName                    }                  }                }              }        }    `;      const getData = (term) => {        fetch(apiEndpoint, {            method: "POST",            headers: { "Content-Type": "application/json" },            body: JSON.stringify({                query,                variables: { term }            })        })            .then(res => res.json())            .then((data) => setData(data))            .catch(console.error);    };    // console.log(data)    return (        <div>            <SearchBar getData={getData} />            {data.data ? data.data.tv.search.edges.map(({ node }) => (                <ShowInfoCard key={node.id} node={node} />            )) : <div></div>            }        </div>    );  }  export default Main;
Step 5: Now, moving on to the SearchBar component, which serves the purpose of receiving the user input for name/keyword. It is a simple component, with an input field of text type, and a button to make the search request. The state variable term is updated holds the input from user, and is passed as an argument to getData() when the user makes the search request.
SearchBar.jsx
import React, { useState } from "react";  function SearchBar({getData}){    const [term, setTerm] = useState("");    const onChange = (e) =>{        setTerm(e.target.value)    }    const onSearch = () =>{        getData(term)    }    return(        <div className="searchbar">        <input             placeholder="Enter the name..."            type="text"             value={term}            onChange={(event) => {onChange(event)}}            onKeyUp={(event) => {onChange(event)}}            onPaste={(event) => {onChange(event)}}        />        <button type="button" className="searchButton"                 onClick={onSearch}>Search        </button>        </div>    );}  export default SearchBar;
Step 6: Our last component, is a reusable UI component, which is basically a Card Component that receives node ( contains the show information ) as props, and just displays it in any chosen format. You can tweak the App.css file to understand the various design aspects. 
ShowInfoCard.jsx
import React from "react";  function ShowInfoCard({ node }) {    return (        <div className="datacontainer">            <div className="dataitem">              Name : {node.originalName}            </div>        </div>    );}  export default ShowInfoCard;
Step 7: Finally, we need to include the MainComponent in App.js file:
App.js
import './App.css';import React from "react";import Main from './components/MainComponent';  function App() {  return (    <div className="App">      <header className="App-header">        <h2>Consuming a GraphQL API</h2>      </header>      <Main />    </div>  );}  export default App;
Step to run the application: To run the application on your system, run the following command:
npm start
Output:
GraphQL API: https://github.com/nerdsupremacist/tmdb
Fetch API: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
anikakapoor
React-Questions
ReactJS
Web Technologies
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
How to set background images in ReactJS ?
How to create a table in ReactJS ?
How to navigate on path by button click in react router ?
ReactJS useNavigate() Hook
React-Router Hooks
Roadmap to Become a Web Developer in 2022
Installation of Node.js on Linux
How to insert spaces/tabs in text using HTML/CSS?
Top 10 Projects For Beginners To Practice HTML and CSS Skills
Convert a string to an integer in JavaScript