DEV Community

Cover image for Building a simple Rick and morty character app with Graphql and Nextjs
Arif Istiak
Arif Istiak

Posted on

Building a simple Rick and morty character app with Graphql and Nextjs

In this blog we are going to see how to consume a GraphQL with Next.js by building an app which "Finds out" which Rick and Morty character the user is.
For the graphql api we are going to use Rick and morty graphql api https://rickandmortyapi.com/graphql from https://rickandmortyapi.com
The purpose of this blog is to show how to consume the GraphQL api so we are not going to the detail of how GraphQL works .

First lets create a new nextjs app with

npx create-next-app who-are-you 
Enter fullscreen mode Exit fullscreen mode

Now cd into the project directory , to start consuming GraphQL we will need to install graphql and @apollo/client

yarn add @apollo/client graphql 
Enter fullscreen mode Exit fullscreen mode

Now goto pages/_app.js file . If there isn't one then create one
the . File is going to look something like this

import "../styles/globals.css";
import {
  ApolloClient,
  InMemoryCache,
  ApolloProvider,
} from "@apollo/client";

const client = new ApolloClient({
  uri: "https://rickandmortyapi.com/graphql",
  cache: new InMemoryCache(),
});

function MyApp({ Component, pageProps }) {
  return (
    <ApolloProvider client={client}>
      <Component {...pageProps} />{" "}
    </ApolloProvider>
  );
}

export default MyApp;
Enter fullscreen mode Exit fullscreen mode

Here we created a new client with the url endpoint and a cache and passed it to the child components through a provider .

Lets create a folder called graphql at the root of the project and create a file called queries.js under this folder
so the folder structure will be like this .
image
In the queries.js file , there will be the query to fetch a specific character with an id

import { gql } from "@apollo/client";

export const GET_CHARECTER = gql`
  query getCharecter($id: ID!) {
    character(id: $id) {
      name
      image
      episode {
        name
      }
      location {
        name
        dimension
      }
    }
  }
`;
Enter fullscreen mode Exit fullscreen mode

So now as everything is in place it's time to query the api and the successful query would retrieve the character name , image , list of episode name that it appeared in and locations with name and dimension , for this we are going to use the useQuery hook

import { useQuery } from "@apollo/client";
import { GET_CHARECTER } from "../graphql/queries";
const randomId = (_) => parseInt(Math.random() * 671);
const { loading, error, data } = useQuery(GET_CHARECTER, {
   variables: {
     id: characterId,
   },
});
Enter fullscreen mode Exit fullscreen mode

Now when the component mounts , useQuery() hook is going to query the GraphQL api with a random character id ( at the time of writing this blog there are 671 characters ). While the query is running , the loading state is going to be true otherwise false , so we can use it to show loading related stuff . If there is any error it is going to be set on the error state of the hook , and if everything is ok the data state will store the data after the query finishes .

so our component would look something like this

import { useQuery } from "@apollo/client";
import { useEffect, useState } from "react";
import { GET_CHARECTER } from "../graphql/queries";
import styles from "../styles/Home.module.css";

const randomId = (_) => parseInt(Math.random() * 671);

export default function Home() {

  const [characterId, setCharacterId] = useState(randomId());
  const { loading, error, data } = useQuery(GET_CHARECTER, {
    variables: {
      id: characterId,
    },
  });
  const [character, setCharacter] = useState();
  useEffect(() => {
    if (data) {
      console.log(data.character);
      setCharacter(data.character);
    }
  }, [data]);
  if(loading) return  <div className={styles.container}> loading...</div> ;
  return (
    <div className={styles.container}>
      You are
      {character && (
        <>
          <h2> {character.name} </h2>
          <img src={character.image} alt={character.name} />
        </>
      )}
      <button
        className={styles.try__again__btn}
        onClick={() => {
          setCharacterId(randomId());
        }}
      >
        {" "}
        try again
      </button>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

the final product would be
1777946a-a66a-49c9-9664-dfcd39e0c59f

here is the live link https://aistiak.github.io/who-are-you
you can find the source code here https://github.com/aistiak/who-are-you .
A star on Github and your feedback about the article would be much would be much appreciated 💖 .And thank you for reading the article

Discussion (0)