NoCodeAPI Google Sheet Tutorial using React and Chakra UI

We are going to build a simple website 'Fungram' with React, Chakra UI, and NoCodeAPI for fetching the data from Google Sheets. The goal of this tutorial is to make you familiar with NoCodeAPI and how it works.

The final project will look something like this (dark mode):

Check out the project live at - fungram.netlify.app

And source code is available at - github.com/fabcodingzest/fungram

Tech-stack we'll be using-

  • React

    React is a JavaScript library for building faster user interfaces with reusable components.

  • Chakra UI

    Chakra UI is a simple, modular and accessible component library that will help us to style our website.

  • NoCodeAPI

    NoCodeAPI makes it easy to set up Google Sheet, Airtable, Twitter, etc APIs.

Getting Started

Let's get started with setting up the project directory.

Creating React project

We will be using the create-react-app template for Chakra UI.

# using npm
npx create-react-app fungram --template @chakra-ui

# or using yarn
yarn create react-app fungram --template @chakra-ui

# Enter the project directory
cd fungram

# Use the following command to open the project in vs-code
code .

We will be making some changes to files and deleting what is not needed (you can skip this step if you want to and go straight to this section).

Delete the following from the src directory

├── App.test.js
├── Logo.js
├── logo.svg
├── reportWebVitals.js
├── serviceWorker.js
├── setupTests.js
└── test-utils.js

This will show some errors, we need to remove the imports of the deleted files so let's do that.

1) Remove Everything inside App.js return function so it will look like this:

import React from 'react';

function App() {
  return (
    <div>
      Hello
    </div>
  );
}

export default App;

2) Moving onto index.js, it will look like this:

import { ChakraProvider, ColorModeScript, theme } from '@chakra-ui/react';
import React, { StrictMode } from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <StrictMode>
    <ChakraProvider theme={theme}>
      <ColorModeScript />
      <App />
    </ChakraProvider>
  </StrictMode>,
  document.getElementById('root')
);

What did we do here?
Since we removed ChakraProvider from App.js, we added it to the index.js (you can have it in App.js too, I just prefer to have it separately in the index file).

3) Starting the server for development:

yarn start
# or
npm run start

So now we are done with setting up the project, let's go to NoCodeAPI to get our endpoint.

Before we move on I just want to show that I am storing some Posts data in the Google sheet that we will be using for the project which looks something like this:

Note: I converted JSON data obtained from DummyAPI to Google sheets using this tutorial. (I know I could have directly imported data using the NoCodeAPI import feature but since the data was nested and not working without the Dummy API header, so I had to go through this and then import the .xlsx file to google sheets manually xD. You learn something new every day.)

Working with NoCodeAPI

First, you will need to sign up of course. After signing in, go to the Marketplace and search for Google sheet or scroll down a bit, you should see one there (as shown in the picture):

You will see the activate button there(since I am already using the API so it shows Use this API for me), click on it. It will redirect you to a page where you should be able to see a Make Google Sheets API yellow button, click on it and you will see the following drawer:

Give your desired name to the API and enter the sheet ID (take help from the example), click on Create and Holaaa! Our Google Sheet API is ready to use. You will see something like this:

Click on use this API and play with the endpoints however you want, just make sure to enter the tabId (E.g. Sheet1 for my case) as it is the required parameter:

Test the API and you should be able to see the results like this:

Hallelujah! Our API is working now all we need to do is use the API endpoint in our React App, Let's goooo!

Coming back to our React Project

First, we will set up our API with the help of Axios.

1) To install Axios, run the following command in the terminal:

# using Yarn
yarn add axios

# or using npm
npm install axios

2) Create an api folder containing api.js and add the following code:

import axios from 'axios';

export default axios.create({
  baseURL: "Your api endpoint from NoCodeAPI",
  params: {
    tabId: 'Sheet1', // passing the required parameter in the axios instance of api
  },
});

We can't have the API string available publicly so we will store it as an environment variable in a .env file, so let's quickly create one and add our API endpoint with the prefix REACT_APP_ (that is how create-react-app works, you gotta have this), I am gonna go with the following.

REACT_APP_API=your_nocodeapi_endpoint

Now that we are done with this, let's change the baseURL in api.js , so it will look like this:

import axios from 'axios';

export default axios.create({
  baseURL: process.env.REACT_APP_API,
  params: {
    tabId: 'Sheet1',
  },
});

Yay! We are ready to work on our components now.

Let's come back and fetch some data from the api in App.js, we will be using the useEffect hook but before that let's add some states to the component using useState hook (don't forget to import it).

const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');

The states are self-explanatory so let's move onto the useEffect function which will look something like this:

import api from './api/api'; // importing the api

useEffect(() => {
    const fetchData = async () => {
      setLoading(true);
      try {
        const res = await api.get('/');
        setPosts(res.data.data);
      } catch (error) {
        setError(error.message);
      }
      setLoading(false);
    };
    fetchData();
  }, []);

What did we do here?

  • We created an async function, in which we first set our loading state to true since our data is yet to be fetched.
  • In the try block, we are awaiting the response from api and saving it in the res variable.
  • After we get our data, we use the setPosts function provided by the useState hook.
  • In case of any error we catch, we set the error state to the error message.
  • After the process ends we set the loading state back to false.
  • At last, we call the function inside the hook, this will run whenever the App component renders.

We will create a components folder inside the src directory. Remember we have a ColorModeSwitch.js file, move it to the components folder as well.

Now, let's code our App component.

// Adding these in case of data is loading or there is some error
// The components used are simply Chakra UI components (import them)

if (loading)
    return (
      <Flex alignItems={'center'} justifyContent={'center'} minH={'100vh'}>
        <Spinner size="xl" thickness="4px" />
      </Flex>
    );
  if (error) return (
    <Flex alignItems={'center'} justifyContent={'center'} minH={'100vh'}>
      {error}
    </Flex>
  );

// when we get the data
  return (
    <div>
      <Box bg={'teal.600'}>
        <Container as={'header'} maxW={'container.xl'} py={6}>
          <Flex
            w={'full'}
            alignItems={'center'}
            justifyContent={'space-between'}
          >
            <Text
              color={'white'}
              fontSize={'4xl'}
              fontWeight={'600'}
              textTransform={'uppercase'}
            >
              fungram
            </Text>
            <ColorModeSwitcher justifySelf="flex-end" />
          </Flex>
        </Container>
      </Box>

      <Container as="main" maxW="container.xl" my={10}>
        <Grid
          templateColumns={{
            base: 'repeat(1, 1fr)',
            md: 'repeat(2, 1fr)',
            lg: 'repeat(3, 1fr)',
          }}
        >
          {posts.map(post => (
            <PostCard key={post.id} data={post} />
          ))}
        </Grid>
      </Container>
      <Box bg={'teal.600'}>
        <Container as={'footer'} maxW={'container.xl'} align={'center'} py={6}>
          <Text fontSize={'sm'}>
            &copy; 2021 Made by{' '}
            <Link fontWeight={'600'} href="http://github.com/fabcodingzest">
              Fab
            </Link>
          </Text>
          <Text fontSize={'sm'}>
            Checkout the code at{' '}
            <Link
              fontWeight={'600'}
              href="http://github.com/fabcodingzest"
            >
              GitHub
            </Link>
          </Text>
        </Container>
      </Box>
    </div>
  );

Again, what did we do here?

  • Chakra UI components are used for styling the header, footer and main elements (don't forget to import them).
  • We used the ColorModeSwitch component in the header.
  • The main part was mapping through the posts state which contains our array of data.
  • We render <Postcard /> component for each item in the array and pass the data as data prop along with of course key prop.

Now, we haven't created PostCard Component yet, so let's create it inside src/components/ which will look something like this:

import {
  Image,
  Box,
  Tag,
  Center,
  Heading,
  Text,
  Stack,
  Avatar,
  useColorModeValue,
  HStack,
} from '@chakra-ui/react';

const PostCard = ({ data }) => {
  const {
    image,
    tags,
    text,
    publishDate,
    ownerFirstName,
    ownerLastName,
    ownerImage,
  } = data;
  const date = new Date(publishDate).toLocaleDateString();
  const tagsArr = tags.split(', ');
  return (
    <Center py={6}>
      <Box
        maxW={'350px'}
        w={'full'}
        bg={useColorModeValue('white', 'gray.700')}
        boxShadow={useColorModeValue('2xl', 'sm')}
        rounded={'md'}
        p={6}
        overflow={'hidden'}
      >
        <Box
          h={'210px'}
          bg={'gray.100'}
          mt={-6}
          mx={-6}
          mb={6}
          pos={'relative'}
        >
          <Image
            src={image}
            objectFit={'cover'}
            h={'full'}
            w={'full'}
            alt={text}
          />
        </Box>
        <Stack>
          <HStack spacing={2}>
            {tagsArr.map(item => (
              <Tag size={'sm'} key={item} variant="solid" colorScheme="teal">
                {item}
              </Tag>
            ))}
          </HStack>
          <Heading
            color={useColorModeValue('gray.700', 'white')}
            fontSize={'xl'}
            fontFamily={'body'}
            textTransform="capitalize"
            noOfLines={2}
          >
            {text}
          </Heading>
        </Stack>
        <Stack mt={6} direction={'row'} spacing={4} align={'center'}>
          <Avatar src={ownerImage} alt={'Author'} />
          <Stack direction={'column'} spacing={0} fontSize={'sm'}>
            <Text fontWeight={600}>
              {ownerFirstName} {ownerLastName}
            </Text>
            <Text color={'gray.500'}>{date}</Text>
          </Stack>
        </Stack>
      </Box>
    </Center>
  );
};

export default PostCard;

What did we do here?

  • We first destructured the data prop we received.
  • Converted the publishDate to a local date string.
  • Split the tags string and get an array of tags (this is because of the way I stored tags in Google Sheets).
  • Rest we just use Chakra UI for the styles.

Hallelujah! We are done with the project, but there is a lot more you can do with NoCodeAPI so make sure to play around with other kinds of requests or products in the marketplace. All the best!

Summary

  • We learned how to create React project with the Chakra UI template.
  • We learned how to set up Google Sheet API using NoCodeAPI.
  • We learned how to fetch data, handle loading and error states.

39