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):

screenshot.png

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-

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:

xlsx.png

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

</aside>

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):

google.png

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:

form.png

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:

spi.png

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:

s1.png

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

s2.png

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 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?

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?

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