52

When I execute the following code from my browser the server gives me 400 and complains that the request body is missing. Anybody got a clue about how I can pass a simple string and have it send as the request body?

 let content = 'Hello world' 
 axios.put(url, content).then(response => {
    resolve(response.data.content)
  }, response => {
    this.handleEditError(response)
  })

If I wrap content in [] it comes thru. But then the server receives it as a string beginning with [ and ending with ]. Which seems odd.

After fiddling around I discovered that the following works

  let req = {
    url,
    method: 'PUT',
    data: content
  }
  axios(req).then(response => {
    resolve(response.data.content)
  }, response => {
    this.handleEditError(response)
  })

But shouldn't the first one work as well?

David Schumann
  • 13,380
  • 9
  • 75
  • 96
user672009
  • 4,379
  • 8
  • 44
  • 77

8 Answers8

32

I solved this by overriding the default Content-Type:

const config = { headers: {'Content-Type': 'application/json'} };
axios.put(url, content, config).then(response => {
    ...
});

Based on my experience, the default Content-Type is application/x-www-form-urlencoded for strings, and application/json for objects (including arrays). Your server probably expects JSON.

Diggy.
  • 6,744
  • 3
  • 19
  • 38
nagy.zsolt.hun
  • 6,292
  • 12
  • 56
  • 95
  • 1
    Yep, you are absolutely right. [Here](https://masteringjs.io/tutorials/axios/put) is a certain detail about axios.put. – liuliang Aug 30 '21 at 09:22
25

This works for me (code called from node js repl):

const axios = require("axios");

axios
    .put(
        "http://localhost:4000/api/token", 
        "mytoken", 
        {headers: {"Content-Type": "text/plain"}}
    )
    .then(r => console.log(r.status))
    .catch(e => console.log(e));

Logs: 200

And this is my request handler (I am using restify):

function handleToken(req, res) {
    if(typeof req.body === "string" && req.body.length > 3) {
        res.send(200);
    } else {
        res.send(400);
    }
}

Content-Type header is important here.

David Schumann
  • 13,380
  • 9
  • 75
  • 96
kzg
  • 780
  • 9
  • 22
15

I was having trouble sending plain text and found that I needed to surround the body's value with double quotes:

const request = axios.put(url, "\"" + values.guid + "\"", {
    headers: {
        "Accept": "application/json",
        "Content-type": "application/json",
        "Authorization": "Bearer " + sessionStorage.getItem('jwt')
    }
})

My webapi server method signature is this:

public IActionResult UpdateModelGuid([FromRoute] string guid, [FromBody] string newGuid)
Dranyar
  • 580
  • 1
  • 10
  • 16
  • This is the only way working for me (I'm doing a `post` request), but how? This double-quote solution is like magic. – JJPandari Jun 07 '18 at 06:47
  • If you think about it, the server side is expecting a string data type. Had this string value be the value of a field of an object type, then you would still surround the string value with double-quotes in the json attribute. This is one way to reason about it. – Dranyar Jun 08 '18 at 17:38
  • somehow this works like a charm. I was going nuts. thank you! – omer.ersoy Aug 08 '19 at 13:34
7

Have you tried the following:

axios.post('/save', { firstName: 'Marlon', lastName: 'Bernardes' })
    .then(function(response){
        console.log('saved successfully')
});

Reference: http://codeheaven.io/how-to-use-axios-as-your-http-client/

smottt
  • 3,272
  • 11
  • 37
  • 44
Dimo
  • 467
  • 6
  • 13
5

simply put in headers 'Content-Type': 'application/json' and the sent data in body JSON.stringify(string)

alim91
  • 538
  • 1
  • 8
  • 17
2

Another simple solution is to surround the content variable in your given code with braces like this:

 let content = 'Hello world' 
 axios.put(url, {content}).then(response => {
    resolve(response.data.content)
  }, response => {
    this.handleEditError(response)
  })

Caveat: But this will not send it as string; it will wrap it in a json body that will look like this: {content: "Hello world"}

R G
  • 31
  • 4
  • this is not a caveat, it is just wrong. You are using an ES6 feature for object initialization without understanding it. In ES6 this is a shorthand for { content: content } You are not sending a raw payload, you are creating a standard json object with a "content" propery populated with the raw value. – pdenti Apr 08 '21 at 22:24
1

This worked for me:

export function modalSave(name,id){
  console.log('modalChanges action ' + name+id);  

  return {
    type: 'EDIT',
    payload: new Promise((resolve, reject) => {
      const value = {
        Name: name,
        ID: id,
      } 

      axios({
        method: 'put',
        url: 'http://localhost:53203/api/values',
        data: value,
        config: { headers: {'Content-Type': 'multipart/form-data' }}
      })
       .then(function (response) {
         if (response.status === 200) {
           console.log("Update Success");
           resolve();
         }
       })
       .catch(function (response) {
         console.log(response);
         resolve();
       });
    })
  };
}
Dayan
  • 369
  • 1
  • 5
  • 12
0

this worked for me.

let content = 'Hello world';

static apicall(content) {
return axios({
  url: `url`,
  method: "put",
  data: content
 });
}

apicall()
.then((response) => {
   console.log("success",response.data)
}
.error( () => console.log('error'));
David Schumann
  • 13,380
  • 9
  • 75
  • 96
Vishnu
  • 1,611
  • 1
  • 14
  • 27