question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

POST to API endpoint with fetch()

See original GitHub issue

Hi everyone 👋

I’m implementing Staticman on my GatsbyJS site, and it’s looking great!

The only thing is that I want my comment submission event to adapt to React (no page reload for starters), so I’m turning action="https://dev.staticman.net/..." method="POST" into a handleSubmit function that POSTs the event via fetch():

async handleSubmit(event) {
  event.preventDefault() // stop the form from submitting

  const request = await fetch("https://dev.staticman.net/v3/entry/github/robinmetral/eaudepoisson/master/comments", {
    method: "POST",
    body: event,
  })

  const response = await request.json()
  console.log(response)
}

However I get this error as a response:

errorCode: "MISSING_PARAMS"
data: [fields]
success: false

Staticman doesn’t recognize the required fields in my event object. I’ve also tried to turn the object into a JSON string, but I’ve had the same error.

Is the API endpoint only allowing the x-www-form-urlencoded POST format? Has anyone been using fetch() to POST to Staticman?

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

3reactions
robinmetralcommented, Jan 21, 2019

After some research I’ve found a solution. Here’s my handleSubmit function:

handleSubmit = async (event) => {
  event.preventDefault()

  // extract form data
  const formdata = new FormData(event.target)

  // convert FormData to json object
  // SOURCE: https://stackoverflow.com/a/46774073
  const json = {}
  formdata.forEach(function(value, prop){
    json[prop] = value
  })

  // convert json to urlencoded query string
  // SOURCE: https://stackoverflow.com/a/37562814 (comments)
  const formBody = Object.keys(json).map(key => encodeURIComponent(key) + '=' + encodeURIComponent(json[key])).join('&')

  // POST the request to Staticman's API endpoint
  const response = await fetch("https://dev.staticman.net/v3/entry/github/robinmetral/eaudepoisson/master/comments", {
    method: "POST",
    headers: {"Content-Type": "application/x-www-form-urlencoded"},
    body: formBody,
  })
    .then(response => {
      // reset form
      document.getElementById("comment-form").reset()
      // display success message
      document.getElementById("success").style.display = "block"
    })
    .catch(error => {
      console.log(error)
      document.getElementById("failure").style.display = "block"
    })
}

This is what it does:

  1. it extracts the submitted data as a FormData object
  2. it converts the FormData to a JSON object, using a snippet found on SO
  3. it converts the JSON to the expected application/x-www-form-urlencoded content-type or “query string”, using another SO snippet
  4. it sends the request to the API endpoint, catches errors and displays a success message

It’s probably not the only solution, and if you see something that I could improve, please let me know below or send me a PR!

1reaction
kuworkingcommented, Feb 27, 2019

@robinmetral thanks a lot, it’s worked for me, but, what was driving me nuts was this

Step 3. Hook up your forms Forms should POST to: https://api.staticman.net/v2/entry/{GITHUB USERNAME}/{GITHUB REPOSITORY}/{BRANCH}/{PROPERTY (optional)}

But looking at your code (apart from dev and v3), at the end it seems that should post there: https://dev.staticman.net/v3/entry/github/{GITHUB USERNAME}/{GITHUB REPOSITORY}/{BRANCH}/{PROPERTY (optional)}

So, in my hands, this has worked for me (with semantic-ui):

<Form onSubmit={onSubmit}>
    <Form.Input name="name" onChange={changeUserName} placeholder="what" />
    <Form.TextArea name="message" onChange={changeuserMessage} placeholder="what2" />
    <Form.Button>Submit</Form.Button>
</Form>

and

  const [userName, setUserName] = useState(() => '')
  const [userMessage, setUserMessage] = useState(() => '')
  const wait = ms => new Promise((r, j) => setTimeout(r, ms))

  let changing = 0 // to create a buffer to avoid changing state always, the browser gets slow otherwise
  const changeUserName = async (e, { value }) => {
    changing++
    let prev_changing = changing
    await wait(100)
    if (prev_changing === changing) setUserName(value)
  }

  const changeuserMessage = async (e, { value }) => {
    changing++
    let prev_changing = changing
    await wait(100)
    if (prev_changing === changing) setUserMessage(value)
  }

  const onSubmit = async e => {
    e.preventDefault()
    const formdata = new FormData()
    formdata.set('fields[name]', userName)
    formdata.set('fields[message]', userMessage)
    const json = {}
    formdata.forEach((value, prop) => (json[prop] = value))
    const formBody = Object.keys(json)
      .map(key => encodeURIComponent(key) + '=' + encodeURIComponent(json[key]))
      .join('&')

    // in the repo, create a folder named 'comments'
    const response = await fetch(
      'https://dev.staticman.net/v3/entry/github/{my github user}/{my repo}/master/comments/',
      {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: formBody,
      }
    )
    console.log(response)
  }
Read more comments on GitHub >

github_iconTop Results From Across the Web

Get and Post method using Fetch API - GeeksforGeeks
The fetch() method is used to send the requests to the server without refreshing the page. It is an alternative to the XMLHttpRequest...
Read more >
Fetch API (JavaScript)- How to Make GET and POST Requests
Fetch API comes with a fetch () method that allows you to fetch data from all sorts of different places and work with...
Read more >
Fetch API – How to Make a GET Request and POST Request ...
Fetch API – How to Make a GET Request and POST Request in JavaScript ... Simply call fetch() with the endpoint URL as...
Read more >
Using the Fetch API - MDN Web Docs
The Fetch API provides a JavaScript interface for accessing and manipulating parts of the protocol, such as requests and responses.
Read more >
Fetch API POST Sample
This sample shows how the Fetch API can make POST requests. // Enter some JavaScript here // e.g. Create new GitHub Gist. Live...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found