Vue.js sending vuejs data post request as array of ints instead of strings

Vue.js sending vuejs data post request as array of ints instead of strings,vue.js,vuejs2,axios,Vue.js,Vuejs2,Axios,I have 2 input boxes for weights and values, and I can then click a button to automatically create more. This part is working fine. The problem now is that the server expects a JSON formdata request containing array of ints, rather than strings. This is how the postdata should look like: {"stuff": {"weights": [2, 5, 3], "values": [654, 23, 3]}} This is what it ends up looking like: {"stuff": {"weights": ["2", "5", "3"], "values": ["654", "23", "3"]}} I have tried to search how to set dat

I have 2 input boxes for

weights
and
values
, and I can then click a button to automatically create more. This part is working fine.

The problem now is that the server expects a JSON formdata request containing array of ints, rather than strings.

This is how the postdata should look like:

{"stuff": {"weights": [2, 5, 3], "values": [654, 23, 3]}}

This is what it ends up looking like:

{"stuff": {"weights": ["2", "5", "3"], "values": ["654", "23", "3"]}}

I have tried to search how to set data array type to int, how to save v-model as int, etc.

I believe this is all the relevant code:

<template>
..

<div v-for="(weight, index) in weights">
  <div>
    <label for="w">weight:</label>
    <input v-model="weights[index]">
    <label for="v">value:</label>
    <input v-model="values[index]">
  </div>
</div>

..
</template>

<script>
export default {
  data () {
    return {
      weights: [],
      values: []
    }
  },
  methods: {
    solve: function () {
      var formData = {
        stuff: {
          weights: this.weights,
          values: this.values
        }
      }
      axios.post('http://localhost:8000/my/api/url', formData).then(response => {
        console.log(response)
      }).catch(e => {
        console.log(e)
      })
    },
  ...
</script>

#1

You can use the .number modifier:

<input v-model.number="weights[index]">

But this allows non-integer numbers and strings (it can be an empty string if the input is empty, for example). For this reason, you should explicitly convert the weights to integers at the API call:

// You should validate the data first

var formData = {
  stuff: {
    weights: this.weights.map(x => parseInt(x, 10)),  // Convert to integer
    values: this.values.map(x => parseInt(x, 10))
  }
}

#2

You can use parseInt to convert them:

export default {
  data () {
    return {
      weights: [],
      values: []
    }
  },
  computed: {
    formData() {
        return {
            stuff: {
                weights: this.weights.map((x) => parseInt(x, 10),
                values: this.values.map((x) => parseInt(x, 10)
            }
        }
    }
  },
  methods: {
    solve: function () {
      axios.post('http://localhost:8000/my/api/url', this.formData).then(response => {
        console.log(response)
      }).catch(e => {
        console.log(e)
      })
    },
  ...

I used a computed variable to make the API call code cleaner, but it would work the same in there. The extra argument 10 is important with parseInt, it ensures the integer is base 10 which could otherwise cause odd behavior.


#3

Wow thank you so much! Been struggling with this for hours.. I did see someone on GitHub mention you had to put number, but I foolishly added it as <input v-model="weights[index]" number>.. doh! In my case all input fields will be required, so I think the v-model.number solution is perfect <3

#4

Good answer, I missed they were arrays. I recommend a second argument to parseInt to include the radix of 10. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

#5

Huh I didn't realize the radix parameter could be problematic across implementations. Updated.

#6

I have only once seen it cause a problem in practice, but that day was horrible haha. It happens when the string has a leading 0

#7

Thank you so much <3.. wish I could accept both answers