0

I'm trying an integration with Notion API using Next.JS api to fulfill a table using form values from my site.

The form logic is shown bellow. I'm using Formik to handle values and changes. Handle response just allows me to display a feedback for users on screen using Chakra-UI's toast feature.

This submitForm function is ment to pass values using POST through given URL, following Next.js logic for dynamic API routes. ${urlPath}/api/submit/${title} will reach the handler and pass a value using title to fill the formName value.

//* This is the main file for the form component
import {useToast} from '@chakra-ui/react'
import PropTypes from 'prop-types'
import {useState} from 'react'
import FormPageStructure from './formPageStructure'
import {Form, Formik, Field} from 'formik'
function FormRenderer (props) {
  const {
    title,
    fields,
    buttonLabel,
    successMessage,
    errorMessage
  } = props

  const [serverState, setServerState] = useState()
  const toast = useToast()

  const handleServerResponse = (ok, msg) => {
    setServerState({ok, msg})
    toast({
      title: ok ? 'Mensagem enviada' : 'Erro ao enviar mensagem',
      description: msg,
      status: ok ? 'success' : 'error',
      duration: 9000,
      isClosable: true
    })
  }

  const urlPath = process.env.NODE_ENV === 'production' ? process.env.URL : 'http://localhost:3000'

  const usoArr = fields.filter(({fieldName}) => fieldName === 'uso')
  // console.log('uso', usoArr)
  const atuaçãoArr = fields.filter(({fieldName}) => fieldName === 'atuação')
  // console.log('atuação', atuaçãoArr)

  const submitForm = async values => {
    const res = await fetch(`${urlPath}/api/submit/${title}`, {
      method: 'POST',
      body: JSON.stringify(values, null, 2),
      headers: {'Content-Type': 'application/json'}
    })
    if (res.status === 201) {
      handleServerResponse(true, successMessage)
    } else {
      handleServerResponse(false, errorMessage)
    }
  }
  const initialValues = {
    nome: '',
    email: '',
    tel: '',
    empresa: '',
    mensagem: '',
    atuação: '',
    uso: ''
  }
  return (
    <FormPageStructure {...props}>
      <Formik initialValues={initialValues} name={title} onSubmit={submitForm} >
          <Form name={title}>
            <label htmlFor="nome">
              Nome
              <Field type="text" name="nome" />
            </label>
            <label htmlFor="email">
              Email
              <Field type="email" name="email" />
            </label>
            <label htmlFor="tel">
              Telefone
              <Field type="tel" name="tel" />
            </label>
            <label htmlFor="empresa">
              Empresa
              <Field type="text" name="empresa" />
            </label>
            <label htmlFor="atuação">
              Atuação
              <Field name="atuação" as="select">
                {atuaçãoArr[0].options.map((option, i) => (
                  <option key={i} value={option}>
                    {option}
                  </option>
                ))}
              </Field>
            </label>
            <label htmlFor="uso">
              Uso
              <Field name="uso" as="select">
                {usoArr[0].options.map((option, i) => (
                  <option key={i} value={option}>
                    {option}
                  </option>
                ))}
              </Field>
            </label>
            <label htmlFor="mensagem">
              <Field as="textarea" name="mensagem" />
            </label>
            <button type="submit">{buttonLabel || 'Enviar'}</button>
          </Form>
      </Formik>
    </FormPageStructure>
  )
}

FormRenderer.propTypes = {
  backgroundImage: PropTypes.object,
  backgroundImageSm: PropTypes.object,
  title: PropTypes.string,
  formHeadline: PropTypes.string,
  formTagline: PropTypes.array,
  formInfo: PropTypes.array,
  fields: PropTypes.array,
  buttonLabel: PropTypes.string,
  successMessage: PropTypes.string,
  errorMessage: PropTypes.string,
  privacyMessage: PropTypes.string
}

export default FormRenderer

The handler postInfo function in ../pages/api/submit/[...slug].js should receive the JSON data and update the table using @notionh1/client to reach Notion's API.

const { Client } = require('@notionhq/client');

const notion = new Client({
  auth: process.env.NOTION_TOKEN
});

export default async function postInfo(req, res) {
  const { slug } = req.query;
  const formName = slug[0];
  /* Logic for url pushing: .../api/submit/formName/ -> tags form @ notion db */
  if (req.method !== 'POST') {
    return res
      .status(405)
      .json({ message: `Method ${req.method} not allowed` });
  }
  try {
    const { nome, email, tel, empresa, mensagem, atuação, uso, end1, end2, cep, cidade } = JSON.parse(req.body);
    await notion.pages.create({
      parent: {
        database_id: process.env.NOTION_DATABASE_ID
      },
      properties: {
        Nome: {
          title: [
            {
              text: {
                content: nome,
              },
            },
          ],
        },
        Email: {
          email: email
        },
        Telefone: {
          number: [
            {
              number: {
                content: tel
              }
            }
          ]
        },
        Empresa: {
          empresa: empresa
        },
        'Área de atuação': {
          select: {
            atuação: atuação
          }
        },
        'Tipo de uso': {
          select: {
            uso: uso
          }
        },
        Mensagem: {
          rich_text: [
            {
              text: {
                content: mensagem
              }
            }
          ]
        },
        'Endereço 1': {
          end1: end1
        },
        'Endereço 2': {
          end2: end2
        },
        CEP: {
          cep: cep
        },
        Cidade: {
          cidade: cidade
        },
        Formulário: {
          select: formName || null
        }
      },
    });
    res.status(201).json({ message: 'Form submitted successfully' });
  } catch (error) {
    res.status(500).json({ message: "there was an error" });
  }
}

However, the console is returning 500 (internal server error) as shown bellow. Not sure on what's the issue. console error

My notion integration seems to be set correctly with all content capabilities enabled. Have just changed user capabilities to no user information with no success on POST. It was Read user info including mail address before
Notion config

Eduardo Oliveira
  • 395
  • 2
  • 18
  • If you check the terminal, what error is being thrown in the API route? – juliomalves Aug 17 '22 at 19:53
  • It returns an SyntaxError of an Unexpected token in JSON. Here it is: https://pastebin.pl/view/b605ca5f I've tried throwing the JSON as an alert and it works fine. Perhaps I need to work the input in the API side? – Eduardo Oliveira Aug 17 '22 at 20:15
  • The line throwing the error is `JSON.parse(req.body)`. Which means you're probably not passing the right value in the request's body from the client. If you log `values` inside `submitForm`, what do you get? – juliomalves Aug 17 '22 at 20:24
  • It returns all the values from the form correctly. The only abnormal thing is that there's an undefined empty object `undefined: ""`. Seems like a normal behaviour. `console.log(JSON.stringfy(values, null, 2))` -> https://pastebin.pl/view/804310a8 – Eduardo Oliveira Aug 17 '22 at 20:59

0 Answers0