Vue.js add objects to existing array

30,967

Solution 1

Try :

vm.results =  vm.results.concat(response.data.data);

This will append the array "response.data.data" to the "results" array.

Solution 2

First of all you don't have to use var vm = this;, this.results will work even in your axios (and every other) callbacks in the context of a vue component.

But the actual problem is that you are using the concatenation += operator to add to an array. Simply use push with the spread operator (...) instead and it should work.

axios.get('http://127.0.0.1:8000/api/posts?page=' + this.pageNumber)
.then(response => {
    this.results.push(...response.data.data);

})
Share:
30,967
VividDreams
Author by

VividDreams

Updated on June 11, 2020

Comments

  • VividDreams
    VividDreams almost 4 years

    I'm trying to add elements from json response to my existing array by clicking on a button but I have a problem with adding these elements properly.

    Here I have an empty array called results where I'm storing my data from response.

    export default {
      name: 'Posts',
      props: ['user_id'],
      data: function(){
          return{
              results: [],
              pageNumber: 1,
          }
      },.....
    

    This is my method for getting data:

    getData: function () {
    
        var vm = this;
    
        axios.get('http://127.0.0.1:8000/api/posts?page=' + vm.pageNumber)
        .then(function (response) {
            vm.results += response.data.data;
    
        })
        .catch(function (error) {
        });
    
    },
    

    In this method I'm adding response data to array like this:

    vm.results += response.data.data;

    My respose is correct but after this operation my results array look like: "[object Object],[object Object]..."

    I have also tried to add new elements by push method:

    vm.results.push(response.data.data);

    But then, elements are added in new arrays but I want to add objects to existing array.

    Here is the structure of my response:

    {"current_page":1,
    "data":[
    {
    "id":60,
    "title":"Post 1",
    "body":"Post 1 body",
    "created_at":"2018-06-09 18:33:40",
    "updated_at":"2018-06-09 18:33:40",
    "user_id":8
    },
    {
    "id":61,
    "title":"Post 2",
    "body":"post 2 body",
    "created_at":"2018-06-09 18:33:40",
    "updated_at":"2018-06-09 18:33:40",
    "user_id":8
    },
    etc...]
    
  • connexo
    connexo almost 6 years
    That would make him push an array into his existing array, instead of pushing those elements in his response array.
  • Philip Feldmann
    Philip Feldmann almost 6 years
    @connexo My bad, didn't see the response data was an array. You can still do it with the spread ... operator though.
  • VividDreams
    VividDreams almost 6 years
    Yeah, as @connexo said, it would create new arrays into my existing arrays. What do you mean by spread operator? And I have checked that I still have to use this vm variable instead of this inside axios.
  • Philip Feldmann
    Philip Feldmann almost 6 years
    @VividDreams The spread operator always gets lots of confusion. It is literally three dots, so the ... is part of the code. It takes the content from an object (or array) and spreads it out, so basically pushes every element of the incoming data into the results array. It is super useful in many situations, you can check out the documentation here developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/….
  • connexo
    connexo almost 6 years
    Of course that works - that's what Array.prototype.concat() was designed for. The more modern, preferrable approach in case you have a Babel transpilation in your build process though is using the spread operator .... You better get used to it, you gonna see this everywhere soon.
  • VividDreams
    VividDreams almost 6 years
    Ok, but how to use it in this specific case? results = [...results] + JSON.stringify({...response.data.data}) is not working. What am I getting wrong?
  • connexo
    connexo almost 6 years
    results = [...results, ...response.data.data] The call to JSON.stringify is only for logging (so you see a proper textual representation of the contained objects), not for your real code.
  • VividDreams
    VividDreams almost 6 years
    Ok, thank you. I don't have babel set up, so I can't check right now if this one works or not. Not working in chrome and according to specs it should work on chrome without babel. It gives me an empty array.
  • connexo
    connexo almost 6 years
    this.results.push(...response.data.data); will not work for two reasons: push expects a single array element and adds that after the end of the array it is called on. this is not what you are expecting here, you either have to use arrow syntax .then((response ) => {/*whatever*/}) or use Function.prototype.bind() method like .then(function (response) { /*whatever*/ }.bind(this))
  • connexo
    connexo almost 6 years
    That is not due to the spread operator then, there's got to be something else that ruins it. Also, with any vue template, you have Babel setup included already. Don't use the <script src="/path/to/vue.min.js"> version of Vue, you're missing out on the best part of Vue then.
  • Philip Feldmann
    Philip Feldmann almost 6 years
    @connexo No, no it does not only expect a single array element. Push accepts n parameters as seen here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…. You are right about this, I was overlooking that he was using function syntax as this is just so rarely used nowadays.
  • connexo
    connexo almost 6 years
    Added an example based off your sample data given to prove it works. I recommend you try to identify the error in your code giving you an empty array just for practice reasons - it might help you understand the spread operator.