Search code examples
javascriptvue.jsvcalendar

My vue.js code is getting data repeatedly from the server


I am new to Vue.js and do not understand this completely (please don't mind the indentation)

  methods:{
getdata() {
  if (this.myPage.month === 5) {
    axios.get("http://www.amock.io/api/maymock").then(response => {
      this.Month = response.data.checkInData.Month;
      this.Stat = response.data.checkInData.CheckedInStat;
      this.TotalTarget = response.data.checkInData.TotalTarget;
      this.$emit("TotTarget", this.TotalTarget);
      this.TargetForMonth = response.data.checkInData.CurrentAchieved;
      this.$emit("TotCount", this.TargetForMonth);
  })
}
  if (this.myPage.month === 4) {
    axios.get("http://www.amock.io/api/aprilmock").then(response => {
      this.Month = response.data.checkInData.Month;
      this.Stat = response.data.checkInData.CheckedInStat;
      this.TotalTarget = response.data.checkInData.TotalTarget;
      this.$emit("TotTarget", this.TotalTarget);
      this.TargetForMonth = response.data.checkInData.CurrentAchieved;
      this.$emit("TotCount", this.TargetForMonth);
  })
     }

   },
},

computed: {
attributes() {
  this.getdata();
  let checkindata = [];
  if (this.Click === 0) {
    var entry = new Object();
    (entry.highlight = "red"), (entry.dates = new Date());
    checkindata.push(entry);
    for (var day = 0; day < this.Stat.length; ++day) {
      entry = new Object();
      (entry.highlight = this.Stat[day] === 0 ? "red" : "green"),
        (entry.dates = new Date(2020, this.Month, day + 1));
      checkindata.push(entry);
    }
  }
  if (this.Click === 1) {
    var entry1 = new Object();
    (entry.highlight = "green"), (entry.dates = new Date());
    checkindata.push(entry1);
    for (day = 0; day < this.Stat.length; ++day) {
      entry1 = new Object();
      (entry.highlight = this.Stat[day] === 0 ? "red" : "green"),
        (entry.dates = new Date(2020, this.Month, day + 1));
      checkindata.push(entry1);
    }
  }
  return checkindata;
 }
},

  data() {
return {
  myPage: {},
  Stat: [],
  Month: null,
  TotalTarget: null,
  TargetForMonth: null,
  responded: null
  };
}

I am using a v-calendar plugin and passing data via the attributes function to the Calendar. However, I want the method getdata to get data from the link provided when the variable myPage.month changes and it should do so only once. How myPage changes isn't given here as it is dynamic with the calendar plugin. Currently, it is doing this an infinite number of times which is troublesome. Is there any way to solve this?


Solution

  • You're calling getData() inside a computed property. This is not correct; you should not be mutating state inside a computed property, not to mention it will be called every time the property needs to be recalculated.

    This is something you should do with a watcher instead. Just watch myPage.month for changes and then call getData() in response to those changes.

    Something like this:

    watch: {
      'myPage.month': {
        immediate: true,
        handler() {
          this.getData();
        }
      }
    }
    

    A couple of other improvements:

    • Instead of new Object() just do {} instead.
    • Code like (x = 1), (y = 2) should be 2 separate statements (separated by ; not ,) ideally on separate lines. The () aren't necessary.
    • Actually you can construct the object in one go like this:
    var entry = {
      highlight: "red",
      dates: new Date(),
    };
    checkindata.push(entry);
    
    • Try reducing the duplicated code as much as possible:
    getData() {
      let api;
      switch (this.myPage.month) {
        case 4: api = 'aprilmock'; break;
        case 5: api = 'maymock'; break;
        default: return;
      }
    
      axios.get(`http://www.amock.io/api/${api}`).then(response => {
        this.Month = response.data.checkInData.Month;
        this.Stat = response.data.checkInData.CheckedInStat;
        this.TotalTarget = response.data.checkInData.TotalTarget;
        this.$emit("TotTarget", this.TotalTarget);
        this.TargetForMonth = response.data.checkInData.CurrentAchieved;
        this.$emit("TotCount", this.TargetForMonth);
      });
    }