Submitting Custom form data to Google sheets via React Js
Tags: javascript, react, webdev, programming
Published: 2022-03-14 15:33:30

In this article we will be discussing how to receive custom form data through React JS, often times when we need to do this we always have to pass through No-code APIs and other Middleware APIs that will generate links for us but Google already made sure this can work by creating a script in Google scripts and deploying it.

Requirements to do this include
* Working Knowledge of React Js
* Google Sheets
* Basic Knowledge of Html

The first thing we are going to do is to create react app

You can learn how to do this with the create-react-app command that sets up a working react environment [https://create-react-app.dev/](https://create-react-app.dev/)

Then you clear up the unnecessary files you don’t need

The first thing we’ll do is to create our react form.
```javascript
  import React, {useState, useRef} from 'react'


const Form = () => {
    const formRef = useRef(null)


  return (
    <div>
        <form method="post" ref={formRef} name="google-sheet">
        <div className="form-style">
            <input type=""  name="name" placeholder='Your Name *' />
        </div>  
        <div className="form-style">
            <input type="email" name="email" placeholder='Your Email *' />
        </div>
        <div className="form-style">
            <input type="number" name="phone" placeholder='Your Phone *' />
        </div>
        <div className="form-style">
            <input type="submit" name="submit" value="Login" />
        </div> 
        </form>
    </div>
  )
}

export default Form
```

In this little snippet, we built a form that allows the user to enter details like their name, email, and phone number. We also included a submit button that sends the data to the formRef mutable object created by the useRef hook.

The next step is to open our google spreadsheet that will be used to save the data then add each form input name as the column heading.


![submit-data-to-spreadsheet](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/stovzkl7ccc8ulj3vuhg.png)

We then proceed to Extensions → App Scripts then copy this code into the app script, this script creates a function that accepts the data from the post request and stores it in the google sheets.

```javascript
var sheetName = 'Sheet1'
		var scriptProp = PropertiesService.getScriptProperties()
 
		function intialSetup () {
		  var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet()
		  scriptProp.setProperty('key', activeSpreadsheet.getId())
		}
 
		function doPost (e) {
		  var lock = LockService.getScriptLock()
		  lock.tryLock(10000)
 
		  try {
			var doc = SpreadsheetApp.openById(scriptProp.getProperty('key'))
			var sheet = doc.getSheetByName(sheetName)
 
			var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0]
			var nextRow = sheet.getLastRow() + 1
 
			var newRow = headers.map(function(header) {
			  return header === 'timestamp' ? new Date() : e.parameter[header]
			})
 
			sheet.getRange(nextRow, 1, 1, newRow.length).setValues([newRow])
 
			return ContentService
			  .createTextOutput(JSON.stringify({ 'result': 'success', 'row': nextRow }))
			  .setMimeType(ContentService.MimeType.JSON)
		  }
 
		  catch (e) {
			return ContentService
			  .createTextOutput(JSON.stringify({ 'result': 'error', 'error': e }))
			  .setMimeType(ContentService.MimeType.JSON)
		  }
 
		  finally {
			lock.releaseLock()
		  }
		}

```
This is the environment of the script


![submit-data-to-spreadsheet](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/60u5rjo8o6x57t1eyv00.png)

You proceed to save then add permissions. The next thing is to run the script then deploy the script. Make sure you change the access to "Anyone", it will then generate a link which will be used to POST the data to the Spreadsheet.
![submit-data-to-spreadsheet](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zs55fb4z3krppdlaan1n.png)

When this has been completed we’ll return to our react app to build the function that sends the data in the form to the Spreadsheet using the API link that was generated.

We proceed to add the function that will submit the form, this function is a fetch request using the post method. It posts the form data and it uses the Url gotten from our previous image/ deployment.

```javascript

const scriptUrl = "get yours by practicing"
    
    const handleSubmit = (e) =>{
        e.preventDefault()
        
        fetch(scriptUrl, {method: 'POST', body: new FormData(formRef.current)})
        .then(res => {
            console.log("SUCCESSFULLY SUBMITTED")
        })
        .catch(err => console.log(err))
    }

```

The "form" tag should have the property of onSubmit ={handleSubmit} which calls the handleSubmit function during submission. 


![submit-data-to-spreadsheet](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ud0sm20qgmqo5cpz2oy1.png)

The final code and the full code is below with the styling with styled-component
```javascript

import React, {useState, useRef} from 'react'
import styled from 'styled-components'

const Form = () => {
    const formRef = useRef(null)
    const scriptUrl = "get yours by practicing"
    const [loading, setLoading] = useState(false)
  
    const handleSubmit = (e) =>{
        e.preventDefault()
        setLoading(true)

        fetch(scriptUrl, {
        method: 'POST', 
        body: new FormData(formRef.current),
      
    }).then(res => {
            console.log("SUCCESSFULLY SUBMITTED")
            setLoading(false)
        })
        .catch(err => console.log(err))
    }

  return (
    <FormStyle>
        <div className="container">
        <form  ref={formRef} onSubmit={handleSubmit} name="google-sheet">
        <div className="input-style">
            <label htmlFor='name'>
                Name
            </label>
            <input type="text" id="name"  name="name" placeholder='Your Name *' />
        </div>  
        <div className="input-style">
            <label htmlFor='name'>Email</label>
            <input type="email" name="email" placeholder='Your Email *' />
        </div>
        <div className="input-style">
            <label htmlFor='name'>Phone No</label>
            <input type="number" name="phone" placeholder='Your Phone *' />
        </div>
        <div className="input-style">
        
            <input type="submit" value={loading ? "Loading..." : "SEND MESSAGE"} />
        </div> 
        </form>
        </div>
    </FormStyle>  
  )
}

export default Form

const FormStyle = styled.div`
    display: flex;
    justify-content: center;
    align-items: center;

    .container{
        background-color: #F9CFF2;
        margin-top: 10%;
        padding: 10rem 10rem 10rem 10rem;
        display: flex;
        justify-content: center;
        align-items: center;
        @media(max-width: 610px){
            padding: 4rem 4rem 4rem 4rem;
        }

        .input-style{
            padding-top: 0.8em;
            display: flex;
            flex-direction: column;
            gap: 0.8em;
            
            label{
                font-family: 'Poppins', sans-serif;
            }
            
            input{
                outline: none;
                border: none;
                padding: 0.8em;
                border-radius: 2em;
            }
            input[type=submit]{
                background-color: #52154E;
                color: #FFFFFFFF;
                font-weight: bold;

    
            }
        }

    }

`
```
If you have any issues with the code be sure to comment below or hit me up on twitter @SegunTuase