3
votes

I'm looping over an array and rendering a HTML template, this is working great. For one of the columns I need to perform an additional AJAX call using axios, so per row fetch data.

However after the AJAX call finishes, I can't get the template to update.. I've tried both passing the loop variable in as reference and attempting to return the Promise from axios.

I think I understand the basic premise of how the async calls should work, I just can't find the correct way to set this up within a Vue template/component.

E.g:

<tr v-for="venue in venue_results" :key="venue.id">
    <td class="border px-4 py-2">{{ venue.name }}</td>
    <td class="border px-4 py-2">{{ getCampsCount(venue) }} {{ venue.camps_count }}</td>
    <!-- <td class="border px-4 py-2">{{ venue.active_events }}</td> -->
</tr>
<script>
    export default {
        ...
        methods: {
            ...
            async getCampsCount(venue) {
                console.log(venue);

                let camps_count = '...';
                venue.camps_count = '...';

                let this_venue = venue;

                return axios.get(
                    route('api3.venue-courses', {venue: venue.id}),
                    {
                        params: {
                            type: 'Hol',
                            active: 1,
                        },
                    }
                )
                .then(response => {
                    console.log(response.data.meta.total);

                    camps_count = response.data.meta.total;
                    this_venue.camps_count = response.data.meta.total;

                    return camps_count;
                })
                .catch(error => {
                    camps_count = 'n/a';
                    this_venue.camps_count = 'n/a';

                    return camps_count;
                })
                .then(() => {
                    // Always run
                    return camps_count;
                });
            },
        }
    }
</script>
1
You shouldn't be calling data fetching operations (or any operation which mutates the component state to trigger a rerender) directly within the template like that. Just call getCampsCount outside of the template, like within the created hook or somewhere else appropriate.Decade Moon
You shouldn't be fetching every time the DOM is re-rendered. This is expensive and unnecessary. Instead, populate your entire venue_results with the asynchronous data at one go. Instead of making a single request for every row you encounter, try to bundle all of them into one request.Terry
You're better off getting the camps_count on the server side and returning it along with the venue_results so it is a property of venue in your loopjustrusty

1 Answers

1
votes

Use a reference in the loop and access it via index.

<div ref='target' />
this.$refs.target[theIndex].innerText = 'The Value'

You can also create a data member, bind to that, and update in your async handler.

<div>{{results[venue.id]}}</div>
this.results[venue.id] = 'The Value'