Feb 21, 2022 08:13 AM
Hello all, I am a learning developer so hopefully my code is not too confusing.
I want to create a form in React that feeds data onto Airtable. Using the Airtable SDK I am able to do it when I insert the API key into the code.
const base = new Airtable({ apiKey: API_KEY }).base(
"base-name"
)
However, if I use process.env.AIRTABLE_API_KEY it gives an error saying: Uncaught Error: An API key is required to connect to Airtable.
import { useState } from 'react';
require('dotenv').config()
const Airtable = require('airtable');
const base = new Airtable({ apiKey: process.env.AIRTABLE_API_KEY }).base(
"base-name"
)
const table = base("table-name")
const Form = () => {
const [firstNameInput, setFirstNameInput] = useState('');
const [lastNameInput, setLastNameInput] = useState('');
const [emailInput, setEmailInput] = useState('');
const [interestInput, setInterestInput] = useState('');
const [phoneInput, setPhoneInput] = useState('');
const resetForm = () => {
setFirstNameInput('');
setLastNameInput('');
setEmailInput('');
setInterestInput('');
setPhoneInput('');
}
const createData = async () => {
try {
const createdRecord = await table.create([
{
fields: {
firstName: firstNameInput,
lastName: lastNameInput,
email: emailInput,
interest: interestInput,
phone: phoneInput
}
},
])
return createdRecord
} catch (err) {
console.error(err)
}
}
const handleSubmit = async (e) => {
e.preventDefault()
try {
await fetch(createData(), {
method: "POST",
body: JSON.stringify({
firstName: firstNameInput,
lastName: lastNameInput,
email: emailInput,
interest: interestInput,
phone: phoneInput,
}),
})
resetForm()
} catch (err) {
console.error(err)
}
}
return (
<div className='section section-center'>
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="firstNameInput">
Add First Name:
</label>
<input
required
type="text"
name="firstName"
value={firstNameInput}
placeholder="Add First Name"
onChange={(e) => setFirstNameInput(e.target.value)}
/>
<label htmlFor="lastNameInput">
Add Last Name:
</label>
<input
required
type="text"
name="lastNameInput"
value={lastNameInput}
placeholder="Add Last Name"
onChange={(e) => setLastNameInput(e.target.value)}
/>
<label htmlFor="emailInput">
Add Email:
</label>
<input
required
type="text"
name="emailInput"
value={emailInput}
placeholder="Add Email"
onChange={(e) => setEmailInput(e.target.value)}
/>
<label htmlFor="interestInput">
Add Interest:
</label>
<div className="radioGroup">
<input type="radio" value="Consulting" name="interestInput" id="Consulting" onChange={(e) => setInterestInput(e.target.value)} />
<label htmlFor="Consulting"> Consulting </label>
<input type="radio" value="Security" name="interestInput" id="Security" onChange={(e) => setInterestInput(e.target.value)} />
<label htmlFor="Security"> Security </label>
<input type="radio" value="Other" name="interestInput" id="Other" onChange={(e) => setInterestInput(e.target.value)} />
<label htmlFor="Other"> Other </label>
</div>
<label htmlFor="phoneInput">
Add Phone Number:
</label>
<input
required
type="text"
name="phoneInput"
value={phoneInput}
placeholder="Add Phone Number"
onChange={(e) => setPhoneInput(e.target.value)}
/>
</div>
<button
type="submit"
>
Submit
</button>
</form>
</div>
)
}
export default Form
When using process.env.AIRTABLE_API_KEY in a different component that only fecthes data using axios, it is able to to read.
Any help would be greatly appreciated. Thank you!
Solved! Go to Solution.
Feb 22, 2022 05:30 AM
EDIT: Nevermind, this approach works!
I am trying a different approach now. Using a serverless function:
require('dotenv').config()
const Airtable = require('airtable-node')
const airtable = new Airtable({
apiKey: process.env.AIRTABLE_API_KEY
})
.base('baseID')
.table('sometablename')
exports.handler = async (event, context, cb) => {
const method = event.httpMethod
if (method !== 'POST') {
return {
statusCode: 405,
body: 'Only POST Requests Allowed',
}
}
const {
fields
} = JSON.parse(event.body)
console.log(fields);
try {
const item = await airtable.create(
{fields}
)
console.log(item)
if (item.error) {
return {
statusCode: 400,
body: JSON.stringify(item),
}
}
return {
headers: {
Authorization: "Bearer " + process.env.AIRTABLE_API_KEY,
'Content-Type': 'application/json'
},
statusCode: 201,
body: 'Success',
}
} catch (error) {
return {
statusCode: 400,
body: 'Server Error',
}
}
}
This is the code of the Component:
async function handleSubmit(e) {
e.preventDefault()
const
fields = {
firstName : firstNameInput,
lastName : lastNameInput,
email : emailInput,
interest : interestInput,
phone : phoneInput
}
try {
await axios.post(`/api/posting`, {
fields
},)
resetForm();
return fields
} catch (error) {
console.log(error.response)
return null
}
}
And this is the error I get:
{
firstName: 'ReallyLongNameToStandOut',
lastName: 'Last Try',
email: 'asas@ee.com',
interest: 'Other',
phone: '1234'
}
{
error: { type: 'INVALID_PERMISSIONS', message: 'Invalid permissions' }
}
Any ideas on what I should do?
Feb 22, 2022 01:17 AM
I’ve tried using another solution for the form I found here on the forums, using axios and setting the headers. Unfortunately the same problem occurs where I have to set the key in text and cannot use an environment variable. I am very confused as the same application is able to read the variable when fetching data but cannot create data…
Here is what I tried:
const Form = () => {
const [firstNameInput, setFirstNameInput] = useState('');
const [lastNameInput, setLastNameInput] = useState('');
const [emailInput, setEmailInput] = useState('');
const [interestInput, setInterestInput] = useState('');
const [phoneInput, setPhoneInput] = useState('');
const data = {
"fields": {
"firstName": firstNameInput,
"lastName": lastNameInput,
"email": emailInput,
"interest": interestInput,
"phone": phoneInput
}
}
const resetForm = () => {
setFirstNameInput('');
setLastNameInput('');
setEmailInput('');
setInterestInput('');
setPhoneInput('');
}
let url = 'https://api.airtable.com/v0/table-id/table-name'
let axiosConfig = {
headers: {
'Authorization': `Bearer ${process.env.AIRTABLE_API_KEY}`,
'Content-Type': 'application/json'
}
}
const handleSubmit = async (e) => {
e.preventDefault()
axios
.post(
url,
data,
axiosConfig
)
.then(resp => console.log(resp))
.catch(error => console.log(error))
resetForm()
}
Feb 22, 2022 05:30 AM
EDIT: Nevermind, this approach works!
I am trying a different approach now. Using a serverless function:
require('dotenv').config()
const Airtable = require('airtable-node')
const airtable = new Airtable({
apiKey: process.env.AIRTABLE_API_KEY
})
.base('baseID')
.table('sometablename')
exports.handler = async (event, context, cb) => {
const method = event.httpMethod
if (method !== 'POST') {
return {
statusCode: 405,
body: 'Only POST Requests Allowed',
}
}
const {
fields
} = JSON.parse(event.body)
console.log(fields);
try {
const item = await airtable.create(
{fields}
)
console.log(item)
if (item.error) {
return {
statusCode: 400,
body: JSON.stringify(item),
}
}
return {
headers: {
Authorization: "Bearer " + process.env.AIRTABLE_API_KEY,
'Content-Type': 'application/json'
},
statusCode: 201,
body: 'Success',
}
} catch (error) {
return {
statusCode: 400,
body: 'Server Error',
}
}
}
This is the code of the Component:
async function handleSubmit(e) {
e.preventDefault()
const
fields = {
firstName : firstNameInput,
lastName : lastNameInput,
email : emailInput,
interest : interestInput,
phone : phoneInput
}
try {
await axios.post(`/api/posting`, {
fields
},)
resetForm();
return fields
} catch (error) {
console.log(error.response)
return null
}
}
And this is the error I get:
{
firstName: 'ReallyLongNameToStandOut',
lastName: 'Last Try',
email: 'asas@ee.com',
interest: 'Other',
phone: '1234'
}
{
error: { type: 'INVALID_PERMISSIONS', message: 'Invalid permissions' }
}
Any ideas on what I should do?