0

I searched the internet for a solution but none did work so far. I am having a Vue component where I want to load dropdown content afterwards. Since it does not work, I simplified the code such that it should only show me the elements (which are driver names). The problem is, that the v-for seems not to work, as the elements are not created in the DOM.

Here goes the code:

<template>

            <div class="list-group">

                <a class="list-group-item" v-for="driver in drivers">
                    {{driver.name}}
                </a>

            </div>

</template>

<script>
export default {
    name: "DriverComponent",
    data: function (){
        return {
            drivers: [],
        }
    },
    mounted(){
        this.loadDrivers();
        console.log(this.drivers);
    },
    methods: {

        loadDrivers: function(){
            axios.get('/api/drivers')
                .then(
                    (response) => {
                        this.drivers = response.data.data;
                        console.log(this.drivers);
                    }

                )
                .catch(function(error){
                    console.log(error);
                });
            // console.log(this.drivers);
        }
    }
}
</script>

In my app.js:

require('./bootstrap');

window.Vue = require('vue').default;
Vue.component('driver-component', require('./components/DriverComponent.vue').default);
const drivers = new Vue({
    el: '#driv',
});

And my html looks as follows:

    <div id="driv">
        <driver-component></driver-component>
    </div>

As you can see, I added some logs, which look like this: Image of console output

Interestingly, it should be the same array, but the first array is empty but the second has the right values in it.-> EDIT: clarified, thank you

to highlight the problem: i would expect a list like: v-for created list Instead, I get a blank page. It works, if I initialize the drivers array with the data I get in json. However, since I load the data afterwards, it seems not to work

Thank you for your help! BR Johannes

EDIT: I am using "axios": "^0.21" and the controller is:

    public function index(){
        return DriverResource::collection(Drivers::all());
    }

this controller returns the array in a data field, therefore, I set the response.data.data (meaning two times data) The backend returns:

{"data":[{"id":1,"name":"UPS"},{"id":2,"name":"Hermes"}]}
Johannes
  • 1
  • 1
  • The first empty array is coming from the console.log you have right after calling `this.loadDrivers();` inside the mounted hook. This can be empty given that the axios call is not completed by the time this line is executed. The second array is executed inside the axios's resolved promise after assigning the response data to `this.drivers`. Your code works as it is supposed to work. – Chin. Udara Jun 28 '21 at 17:40
  • Additionally, you can use the `created()` event for an earlier API call instead of `mounted()` which is invoked later. See this [question](https://stackoverflow.com/questions/45813347/difference-between-the-created-and-mounted-events-in-vue-js) for an example. – lisymcaydnlb Jun 28 '21 at 17:50
  • @lisymcaydnlb if mounted() is called later then created, then why should i call created()? – Johannes Jun 28 '21 at 19:56
  • @Chin.Udara thank you for the clarification about arrays. unfortunately, the code does not work as I intended it to work, since the elements are not created. It just seems like the v-for is not working – Johannes Jun 28 '21 at 19:58

1 Answers1

0

See the homepage for axios. Under the "Response Schema" section they provide what a response looks like. Specifically for data, it's

{
  // `data` is the response that was provided by the server
  data: {}

  < ... omitted for brevity ... >
}

Please check again what your backend is returning or is supposed to return. Log the whole response you get. The this.drivers = response.data.data; seems to be incorrect, however the this.drivers = response.data; should work.


You didn't say which version of axios you are using or show your configuration so I'm using the following for an example:
axios = ^0.21.1
vue-axios = ^3.2.4

Replaced "name" with "title" to match the response format below:

 {
    "title": "delectus aut autem",

      < ... omitted for brevity ... >
  },

--

loadDrivers: function(){
  Vue.axios.get('https://jsonplaceholder.typicode.com/todos')
      .then(
          (response) => {
            this.drivers = response.data; // <<-- works and many task titles are shown on page
            // this.drivers = response.data.data; // <<-- DOES NOT WORK LIKE FOR YOU, blank page
            console.log(this.drivers);
          }
      )
      .catch(function(error){
        console.log(error);
      });
  // console.log(this.drivers);
}
lisymcaydnlb
  • 150
  • 2
  • 12
  • I am using `"axios": "^0.21"`. I am using a resource in the controller: ``` public function index(){ return DriverResource::collection(Drivers::all()); } ``` Therefore, the array is put in `data` and I need the `data` two times... right? – Johannes Jun 28 '21 at 22:08
  • the backend returns: ``` {"data":[{"id":1,"name":"UPS"},{"id":2,"name":"Hermes"}]} ``` – Johannes Jun 28 '21 at 22:16
  • Could you loop and log only driver names when you get a response? To confirm that they are there. Should see 2 separate lines with UPS and Hermes. Another guess, maybe you have something like [this](https://stackoverflow.com/questions/54228356/getting-error-elements-in-iteration-expect-to-have-v-bindkey-directives-vue) problem, where v-bind:key="driver.id" or something similar is would help. See the official [documentation](https://vuejs.org/v2/guide/list.html#Maintaining-State) part. – lisymcaydnlb Jun 29 '21 at 05:30
  • the log shows, that the drivers names are loaded, I confirmed this... or do I get your question wrong? I tried the v-bind:key="driver.id", but without success – Johannes Jun 29 '21 at 19:40
  • No, you understand correctly. If your data is loaded but not shown then your other setup must be wrong. You could log values directly in HTML to see where they are shown and where not. Moreover, I think you should grab a starter HelloWorld project where everything works out of the box and apply your solution step by step on top of it. It's getting hard to guess by text. It would be helpful if you put an abstracted version of your code to a code example hosting website and added a live link here for anyone interested to play it. Hopefully, you would catch the error yourself in the progress. – lisymcaydnlb Jun 29 '21 at 20:44