Vuex getter с асинхронным значением состояния из вызываемой функции firebase (gaxios) - PullRequest
0 голосов
/ 04 июля 2019

Я использую сочетание нескольких технологий: функции Vue, Vuex, Vuetify, Google Firebase. Этот код работает нормально и обновляет компоненты после асинхронной загрузки данных с помощью моей собственной вызываемой функции firebase getBatchData () , но перед получением данных из firebase в консоли отображаются ошибки:

[Vue warn]: ошибка при рендеринге: «Ошибка типа: невозможно прочитать свойство 'location' из неопределенного"

Мой вопрос следующий - как показать какое-то значение перед тем, как фактические данные будут загружены асинхронно ?

// Действия Vuex (файл actions.js):

import * as EVENT from './mutation-types.js';
import firebase from "firebase/app";
const getBatchData = firebase.functions().httpsCallable('getBatchData');


function convertProjectSummary(values) {

  let projects = [];
  const projectNameCol = 0;
  const locationCol = 1;

  const len = values.length;
  for (var i = 1; i < len; i++) {
    let record = {};
    record.project = values[i][projectNameCol];
    record.location = values[i][locationCol];
    projects.push(record);
  }
  return projects;
}

const actions = {
  updateBatchData: (context) => {
    context.commit(EVENT.SET_LOADING, {loading: true});

    getBatchData().then(resp => {

      let projectSummaryArray = [];
      let projectSummarySheetName = 'Project Summary';

      //separation ranges:
      const valueRanges = JSON.parse(resp.data);
      for (var i = 0; i < valueRanges.length; i++) {
        if (range.includes(projectSummarySheetName)) {
          projectSummaryArray = valueRanges[i].values;
          continue;
        };
      };
      let projectSummaryRecords = convertProjectSummary(projectSummaryArray);
      //=> state.projectRecords:[],
      context.commit(EVENT.UPDATE_PROJECT_SUMMARY, {projectRecords: projectSummaryRecords}); 
      context.commit(EVENT.SET_LOADING, {loading: false});

    }).catch(error => console.log(error))
  }
}
export default actions

// Vuex getters (файл getters.js):

const getters = {      
  //getter function with parameter:
  getProjectInfo: state => {
    const records = state.projectRecords;

    function searchProjectDate(projectName) {
      if (records.length > 0) {
        for(var i=0; i<records.length; i++) {
          if(records[i].project == projectName) {
            return records[i];
          }
        }
      } /* not updated if use the next default value:
      else {
        return {
          project: "data not available",
          location: "data not available",
        };
      }
      */
    }

    //return a closure function
    return searchProjectDate;
  },
}
export default getters

// Vue projectInfo.vue file:

<template>
<!-- asynchronous computed value -->
  <div><p :text="info.location"></p></div>
</template>
<script>
import { mapState, mapGetters} from "vuex";
export default {
  name: "prj-info",
  computed: {
    ...mapState(["currentProject"]),
    ...mapGetters(["getProjectInfo"]),
    info() {
      //getter function with parameter:
      return this.getProjectInfo(this.currentProject);
    }
  }
}
</script>

Моя вина: Вместо кода, который я предоставил, я использую дочерний компонент, и в нем была ошибка:

<template>
  <!-- asynchronous computed value -->
  <div><GreyTextField :text="summary && summary.location" /></div>
</template>

<template>
  <div class="grey-textfield">
    {{theText}}
  </div>
</template>

<script>
export default {
  name: "grey-textfield",
  props: {
    text: {
      type: String,
      default: "Text"
    },
  },
  data() {
    return {
      theText: this.text
    }
  },
  watch: {
    text: function(val, oldVal) {
      this.theText = val;
    },
  },
}
</script>

Я добавил наблюдателя для свойства текста. И теперь это работает. Сожалею. Иногда полезно поделиться кодом, чтобы найти ошибки.

...