endoftheworld
endoftheworld

Reputation: 55

Computed property does not get the data correctly Vue.js ,

Hey i am having a problem with my computed property.

First and foremost i am getting data from my ruby on rails API , it is going well , now i am filtering that data based on their id, i do it in my computed property , but if i console log it it just gives me undefined i cannot access for example the filteredRecords[0].id because it is just empty, however, i can loop through that array and its giving me correct data. I think it has to do with timing, i am getting the data in my created(){} section the filtering is running as well but i just cannot access the data from it directly , that's when i need your help.

Here is how my code looks right now ( i am highlighting the important stuff with arrow):

<template>
  <body>
    <div
      class="container uppercase text-xl font-mono pl-4 font-semibold no-underline text-indigo-dark hover:text-indigo-darker "
    >
      <table>
        
        <tbody>
          <tr class="priority-200 ">
            <td id="writeDay" class="default ">{{ createdDate }}</td>
            <td id="hour" class="default pl-16">
              {{ createdHours }}
            </td>
            <td
             
              id="degree"
              class="defaulted  white--text
            "
              v-show="filteredDatas && filteredDatas[0].temperature"
            >
              {{ filteredDatas[0].temperature }} °C
            </td>
            <td
              
              id="speed"
              class="defaulted"
              v-show="filteredDatas && filteredDatas[0].windspeed"
            >
              {{ filteredDatas[0].windspeed }} km/h
            </td>
          </tr>
        </tbody>
      </table>
-----------------------------------------------------THIS H1, i can loop through my records without problem-----------------------------------------
      <h1
        v-for="(record, index) of filteredRecords"
        :key="index"
        :record="record"
      >
        <div :class="getClass(record)">
          <strong
            v-show="
              record.path === 'rightoleft' &&
                currentlyActive &&
                record.id == currentlyActive.id
            "
            >{{ record.description }}
          </strong>
         
        </div>
      </h1>
-----------------------------------------------------------------------------

    </div>
  </body>
</template>

<script>
import { mapGetters } from "vuex";
import moment from "moment";
export default {
  name: "Table",
  data() {
    return {
      templates: [],
      records: [],
      activeSpan: 0,
      datas: [],
      currentlyActive: null,
    
     
     
    };
  },
  mounted() {
    
    this.start();
    
 
  },

  computed: {
    ...mapGetters({
      id: "id",
      dataId: "dataId"
    }),

    createdDate() {
      return moment().format("DD-MM-YYYY ");
    },
    createdHours() {
      return moment().format("HH:mm ");
    },
-----------------------------------------------THATS HOW I FILTER THROUGH MY RECORDS ARRAY WHAT WAS GIVEN FROM AN API

    filteredRecords: function() {
      let localId = this.id;
      let filtered = this.records.filter(record => {
        return record.template_id == localId;
      });
   
      console.log(filtered);
    
      this.anyad = filtered;
      return filtered;
    },

--------------------------------------------------------------------------  
  filteredDatas: function() {
      let localId2 = this.dataId;
      let filtered2 = this.datas.filter(data => {
        return data.id == localId2;
      });
   
      return filtered2;
    }
  },
  methods: {


 
    getClass(record) {
      return {
        rightoleft: record.path === "rightToleft",
       
      };
    },
         ------------------------------------------------------
    start() {
    
      this.currentlyActive = this.filteredRecords[0];    -----> I CANNOT GET THIS ONE ITS GIVING ME NOTHING HELP ------------------------------
      if (!this.currentlyActive) return;
      setTimeout(() => {
        this.nextRecord();
      }, this.currentlyActive.time * 1000);
    },
    nextRecord() {
      let currIndex = this.filteredRecords.findIndex(
        f => f === this.currentlyActive
      );
      if (currIndex === this.filteredRecords.length - 1) {
    
        this.currentlyActive = this.filteredRecords[0];
      } else {
        this.currentlyActive = this.filteredRecords[currIndex + 1];
      }

      setTimeout(() => {
        this.nextRecord();
      }, this.currentlyActive.time * 1000);
    }
     ----------------------------------------------------------------
  },

  created() {
  
    if (!localStorage.signedIn) {
      this.$router.replace("/");
    } else {
      this.$http.secured
        .get("/api/v1/records")
        .then(response => {
          console.log(response.data);
          this.records.splice(0, this.records.length - 1, ...response.data);
        })
        .catch(error => this.setError(error, "Something went wrong"));
      this.$http.secured
        .get("/api/v1/templates")
        .then(response => {
          this.templates = response.data;
        })
        .catch(error => this.setError(error, "Something went wrong"));
      this.$http.secured
        .get("/api/v1/data")
        .then(response => {
          this.datas = response.data;
        })
        .catch(error => this.setError(error, "Something went wrong"));
    }
  }

};
</script>


 <style>

.rightoleft {
  margin-top: 100px;
  color: yellow;
  width: 1000px;
  height: 1000px;
  animation: move 20s linear infinite;
}


@keyframes move {
  0% {
    transform: translate(50px);
    opacity: 1;
  }
  90% {
    transform: translate(800px);
    opacity: 1;
  }

  92% {
    transform: translate(800px);
    opacity: 0;
  }
  94% {
    transform: translate(800px);
    opacity: 1;
  }
  96% {
    transform: translate(800px);
    opacity: 0;
  }
  98% {
    transform: translate(800px);
    opacity: 1;
  }
  /* 60% {
    transform: translate(500px);
    opacity: 1;
  } */

  100% {
    opacity: 1;
    transform: translate(50px);
  }
}
</style>

DESIRED OUTPUT: https://codesandbox.io/s/blue-sun-sm8tl?file=/src/components/HelloWorld.vue

Thats exactly how i want to output like its on sandbox ,on sandbox its working because i am giving it manually the records so it can find for example the filteredRecords[0].id

Can you help me please with that?? what should i do ? Should i copy this thing to another array? if so how do i do that, because the v-for works but accessing it doesnt .

Thanks.

Upvotes: 0

Views: 167

Answers (1)

Boussadjra Brahim
Boussadjra Brahim

Reputation: 1

In the mounted hook that data is not available yet because that data is got in asynchronous way, to deal with this behavior i suggest to use watch property instead of mounted hook:

watch:{
  filteredRecords:{
    handler(newVal,oldVal){
    if(newVal.length>0 && newVal.length!==oldVal.length){
      this.start()
     }
   },
  deep:true

  }
}

Upvotes: 1

Related Questions