0

The data in the Vue.js array with JSON objects in it is mixed up after reloading them from Spring backend.

I am trying to make a frontend with Vue.js for editing the data on the Spring backend. Vue.js makes a call to the backend with axios, it returns a list of items that is rendered on the page with a v-for. The items can be edited separately, when the 'Save' button is clicked for an item, the item is sent to the backend and the data is updated in the database. After this, when I hit reload in the browser (or close and open the same page) the data is reloaded from the server but its mixed up.

loadExercises(){     
           axios({url:'http://localhost:5000/exercises/all'}).then(resp => {
                    this.exercises = resp.data;
                })
            }

This is the function that loads the data.

This is the array originally : https://i.stack.imgur.com/67OJv.jpg

This is the array after reload, I edited the first entry: https://i.stack.imgur.com/i6Zp4.jpg

The backend returns the correct objects, the only difference is the that the entry which was edited is the last in the array (and it was the first in the example case before the edit). The id-s do not change during saving, just the details are updated, like name or description.

This is the part of the template that generates the html, just in case it is because something in there.

<div role="tablist" id="container" v-bind:key="ex.id" v-for="ex in exercises">
            <b-card no-body class="mb-1 customcard">
                <b-card-header header-tag="header" class="p-1 alignleft" role="tab"  v-b-toggle="`accordion${ex.id}`">
                    <span>{{ex.name}}</span>
                </b-card-header>
                <b-collapse v-bind:id="`accordion${ex.id}`" accordion="my-accordion" role="tabpanel">
                    <b-card-body class = "alignleft">
                        <p class="card-text">
                            Name: <b-form-input
                                v-bind:value="`${ex.name}`"
                                v-bind:id="`input${ex.id}`"
                                v-on:input="saveExName(ex.id)"></b-form-input>
                            Target: {{ex.target}} <b-form-select v-on:input="onTargetChange(ex.id)"
                                                                 v-bind:id="`target${ex.id}`" >
                            <option v-bind:key = "target" v-for="target in targets" :value="target" >{{target}}</option>

                            </b-form-select>
                            Description: <b-form-textarea
                                v-bind:value="`${ex.description}`"
                                :rows="3"
                                :max-rows="6"
                                v-on:input="saveExDesc(ex.id)"
                                v-bind:id="`textarea${ex.id}`"></b-form-textarea>
                        </p>
                        <div class="alignright">
                            <b-button v-on:click="saveExUpdate(ex.id)">Save</b-button>
                        </div>

                    </b-card-body>
                </b-collapse>
            </b-card>
        </div>

Any ideas why this is happening?

  • Make sure that you have consistent sorting when you call your `http://localhost:5000/exercises/all`. Sort by `id` ASC/DESC – ljubadr Jan 15 '19 at 22:23
  • Or sort it on your frontend in `loadExercises()`, before you assign the `this.exercises = resp.data` – ljubadr Jan 15 '19 at 22:26
  • @ljubadr Thank you for your comment! I added a line on the backend to randomly shuffle the items before sending to Vue.js and it has the same effect, it is mixed up. Also the resp.data is already ruined when I logged it on the console. I cannot believe that Vue cannot handle this issue – Tamás Regőczi Jan 15 '19 at 22:35
  • This is not issue with vue. Vue is there to display the data, not to change it. – ljubadr Jan 15 '19 at 22:38
  • You need to either remove **random shuffle**, or sort the data on the frontend. You can sort the data on the frontend even if it's shuffled on the backend. It could be simple sort [like this](https://stackoverflow.com/a/12900176/3226121) – ljubadr Jan 15 '19 at 22:40
  • In your `loadExercises()` try to add sorting `this.exercises = resp.data.sort(function(a, b) { return a.id - b.id });` – ljubadr Jan 15 '19 at 22:43
  • I added the random shuffle to experiment if it is really the order of the items, and not something else, the edit maybe. I will sort them on the backend, it is not big deal, it is just frustrating. I even called forceUpdate() after loading the data, but still. Again, thank you for your answer! – Tamás Regőczi Jan 15 '19 at 22:46
  • No problem, I'm glad I could help – ljubadr Jan 15 '19 at 22:49

0 Answers0