Drücke „Enter”, um zum Inhalt zu springen.

VUE.JS: Array gefüllt mit Ergebnissen aus Asynchronen Abrufen wird nicht verwendet

Manuel 0

Mehrere Stunden hat mich ein Problem gekostet, dessen Lösung am Ende dann recht einfach war.

Das Problem

Ich habe ein Component, in welchem die Daten

  data: function() {
      return {
          peopleFile: {},
      };
  },

definiert sind und über die Methode getPeople Daten abgerufen werden, die in Schleife dann zu weiteren Datenabrufen verwendet werden:

getPeople: async function() {
    this.$root.loading = true;
    await people..where('searchglobal', this.entrysSearch).page('size', this.entrysPerPage).page('number', this.page).orderBy(this.entrysOrderBy).get().then(response => {
        this.people = response;
        for (var i = 0; i < this.contacts.data.length; i++) { this.getPeopleFile(this.people.data[i]); } this.$root.loading = false; }).catch(error => {
        this.$root.loading = false;
    });
}, getPeopleFile: async function(peopleObject) {
    peopleObject.PeopleFile().first().then(response => {
        this.peopleFile[peopleObject.id] = response.image.encoded;
    }).catch(error => {
        this.peopleFile[peopleObject.id] = false;
    });
},

Für den Abruf verwendet ich die Bibliothek vue-api-query (https://github.com/robsontenorio/vue-api-query) für welche ich bereits die passenden und auch funktionierenden Models definiert habe.
Die Rückmeldung von getPeople sieht in etwa so aus

{
    "current_page": 1,
    "data": [{
        "id": 2,
        "name": "IT",
    }, ],
    "first_page_url": "http://127.0.0.1/people?sort=name&page%5Bsize%5D=100&page%5Bnumber%5D=1",
    "from": 1,
    "last_page": 1,
    "last_page_url": "http://127.0.0.1/people?sort=name&page%5Bsize%5D=100&page%5Bnumber%5D=1",
    "next_page_url": null,
    "path": "http://127.0.0.1/people",
    "per_page": 100,
    "prev_page_url": null,
    "to": 1,
    "total": 1
}

während die Rückmeldung von getPeopleFile so aussieht:

{
  "current_page": 1,
  "data": [
    {
      "id": 4,
      "name": "test",
	  "parentId": "2",
      "image": {
        "encoded": "data:image/jpeg;base64,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",
        "mime": "image/jpeg",
      }
    }
  ],
  "first_page_url": "http://127.0.0.1/peopleFile/2/files?page%5Bnumber%5D=1",
  "from": 1,
  "last_page": 1,
  "last_page_url": "http://127.0.0.1/peopleFile/2/files?page%5Bnumber%5D=1",
  "next_page_url": null,
  "path": "http://127.0.0.1/production/peopleFile/2/files",
  "per_page": 25,
  "prev_page_url": null,
  "to": 1,
  "total": 1
}

Es gibt in der Component ein View, das wie folgt definiert ist und auf die Daten von peopleFile zurückgreifen soll:


<div class="col-lg-3 col-md-3" v-for="(contact, contactNo) in contacts">
  
<div class="thumbnail">
    
<div class="box-responsible">
      <img class="img-responsive" :src="peopleFile[contact.id]"> {{ contact.id }}
    </div>

  </div>

</div>

Problem an der Stelle nun: Er wollte einfach nicht auf peopleFile zugreifen, egal was ich gemacht habe.

Die Lösung

Ursächlich für das Problem ist wohl an der Stelle, dass mehrere ansynchrone Aufrufe stattfinden können, die dann dafür sorgen dass VUE.JS nicht mehr reactive auf die Variable peopleFile reagiert. Hierfür gibt es aber auch eine recht einfache Lösung:

          Axios.all(
              this.contacts.data.map(item =>
                  item
                  .PeopleFile()
                  .first()
              )
          ).then(
              Axios.spread((...PeopleFileLists) => {
                  this.peopleFile = PeopleFileLists;
              })
          );

Bei diesem Aufruf werden nun die einzelnen Objekte, abgerufen aus getPeople an Axios übergeben welches dann wiederum die mehreren Aufrufe zusammenfasst und das Ergebnis in PeopleFileList speichert, was man in peopleFile ablegen kann und sich dann reactive verhält.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.