Массив, возвращающий undefined в Vue из indexedDB - PullRequest
0 голосов
/ 30 апреля 2020

console.log в моей indexedDB работает и возвращает желаемый результат; массив объектов, который в данный момент находится в магазине. Так что мой код там правильный. Я собираюсь использовать эту информацию для создания таблицы. Однако в Vue возвращается неопределенное. Я пытаюсь установить массив league в Vue равным массиву результатов, который дает indexedDB, но он возвращает undefined.

Это код в Vue:

<script>
import * as db from "../db/db.js";

export default {
  name: "leaguesTable",
  data: function() {
    return {
      leagues: []
    };
  },
  created: function() {
    this.leagues = db.getAllInStore("meta", "leagues");
    console.log(this.leagues);
  }
};
</script>

Это мой индексированный код БД:

function getAllInStore(dbName, storeName) {
  let db;

  var request = indexedDB.open(dbName, 1);

  request.onerror = function(event) {
    alert("Database error" + event.target.errorCode);
  };

  request.onsuccess = function(event) {
    db = event.target.result;
    let tx = db.transaction(storeName, "readonly");

    tx.onerror = function(event) {
      alert("Transaction error" + event.target.errorCode);
    };

    let store = tx.objectStore(storeName);

    let result = store.getAll();

    tx.oncomplete = function() {
      alert("This should work");
      console.log(result.result);
      return result.result;
    };
  };
}

1 Ответ

0 голосов
/ 30 апреля 2020

В созданном хуке вам необходимо убедиться, что вы возвращаете значение из db.getAllInStore, чтобы this.leagues принимало это значение.

Далее, в функции getAllInStore result.result возвращается из транзакция, но не в onComplete или в функции getAllInStore.

Поскольку база данных использует перехватчики событий, такие как onError и onComplete, возврат запроса не даст вам результата вызова базы данных. Чтобы вернуть значение асинхронной операции c в javascript, обычно используются обратные вызовы или обещания. В приведенном ниже примере используются обещания для решения проблемы.

Vue JS:

<script>
import * as db from "../db/db.js";

export default {
  name: "leaguesTable",
  data: function() {
    return {
      leagues: []
    };
  },
  // async is necessary to use await
  created: async function() {
    // await is es2016 syntactic sugar for retrieving the value of a promise
    this.leagues = await db.getAllInStore("meta", "leagues");
    console.log(this.leagues);
  }
};
</script>

IndexDB:

function getAllInStore(dbName, storeName) {
  // resolve param is a function that signifies a successful operation
  // reject param is a function that should be called whenever a check or error occurs
  return new Promise((resolve, reject) => {
    let db;
    let request = indexedDB.open(dbName, 1);
      request.onerror = (event) => reject(event);
      request.onsuccess = (event) => {
        db = event.target.result;

        let tx = db.transaction(storeName, "readonly");
        request.onerror = (event) => reject(event);

        let store = tx.objectStore(storeName);
        let result = store.getAll();
        tx.oncomplete = (result) => resolve(result.result);
      };
  });
}

Дополнительная литература:

...