Search code examples
javascriptpythonflaskweb-component

POST request working with curl but not with Javascript Web components


My HTTP post request for flask rest API is working fine with curl but When trying to post with front-end its says 400 bad requests and in server, it says none type object is not subscriptable(request.json['email'])

Here is my code to front end

const templateSubs = document.createElement("template");

templateSubs.innerHTML = ` 
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<link href="https://fonts.googleapis.com/css2?family=Piazzolla:wght@100&display=swap" rel="stylesheet">

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">

<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx"
crossorigin="anonymous"></script>  

<div class="card m-5" style="width: 18rem;">
<div class="card-body">
<h1 class="card-title text-center" style="font-family: 'Piazzolla', 'serif';">Attim</h1>
<p class="text-center">Get Latest Updates</p>
<form id="form"  method="post">
<div class="form-group">
<input type="email" class="form-control form-control-sm" id="email" placeholder="[email protected]"
aria-describedby="emailHelp" name="email">
<br> <br>
<div class="text-center">
<input type="submit" class="subbtn btn btn-outline-primary btn-sm text">
</div></div>
</form>
</div>
</div>
`;

class SubscriberComp extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: "open" });
    this.shadowRoot.appendChild(templateSubs.content.cloneNode(true));
  }

   connectedCallback() {
    const form = this.shadowRoot.getElementById('form')
    form.onsubmit = async (e) => {
      e.preventDefault();

      const formData = this.shadowRoot.querySelector('#email').value;
      // console.log(formData)

       /*if (formData.get('email') != null) {*/
      let email = {
        "email": formData
      };
       console.log((email))
      fetch("http://localhost:5002/email/add",{
        method:'POST',
        mode: 'no-cors',
        headers: {
          'Content-Type': 'multipart/form-data'
          // 'Content-Type': 'application/x-www-form-urlencoded',
        },
        body : email
      

      }).then(function(res){
        // return res.json()
        return res;
        
      }).then(function(data){
        console.log(data)
      })
      .catch((err) => {console.log(err)});
  
    }}}


window.customElements.define("subs-comp", SubscriberComp);

> Blockquote

If anyone can help me I am trying to solve this from past week, Thanks in advance


Solution

  • The body is incorrectly formatted. It should not be an object but rather form data formatted, e.g. "key1=val1&key2=val2". So try this instead:

    const email = this.shadowRoot.querySelector('#email').value;
    const formData = new FormData();
    formData.append('email', email);
    console.log(email);
    fetch('http://localhost:5002/email/add', {
      method: 'POST',
      mode: 'no-cors',
      headers: {
        'Content-Type': 'multipart/form-data',
        // 'Content-Type': 'application/x-www-form-urlencoded',
      },
      body: formData,
    })
      .then(function(res) {
        // return res.json()
        return res;
      })
      .then(function(data) {
        console.log(data);
      })
      .catch(err => {
        console.log(err);
      });
    

    If server in fact wants JSON the request should rather look like:

    const payload = {
      email: formData
    };
    
    fetch("http://localhost:5002/email/add",{
      method:'POST',
      mode: 'no-cors',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(payload)
    })