3

I'm trying to update a Vue component property, station, when one of several other properties are updated. It wouldn't work as a computed property because computed properties are synchronous and this requires an API request.

Based on an issue reply in Vue core I found the docs on vm.$watch. This looks to be what I need, but I can't figure out how it should be implemented in the context of this component context.

I think I should be using this in place of vm in the docs, but I'm not sure about that. Then again, using this on the left side of the arrow function that's the first parameter of $watch throws errors like Invalid left-hand side in arrow function parameters.

My use of vm.$watch is toward the end of the following component code. The error I keep getting is: Failed watching path: "[object Object]" Watcher only accepts simple dot-delimited paths. For full control, use a function instead. (I thought I was...)

<template lang="html">
  <div>
    {{ station }}
  </div>
</template>

<script>
import ApiService from '@/services/ApiService';

export default {
  name: 'Chart',
  props: {
    mode: String,
    toDate: String,
    toTime: String
  },
  data() {
    return {
      stationId: 3069,
      station: {}
    };
  },
  watch: {
    station: function() {
      // Render function
    }
  },
  methods: {
    getInfo: async function(opts) {
      const stationData = await ApiService[this.mode]({
        id: opts.id,
        toTime: `${opts.toDate}T${opts.toTime}`,
        fromTime: `${opts.fromDate}T${opts.fromTime}`
      })
        .then(res => {
          return res.data.station.properties;
        })
        .catch(err => {
          console.error(err);
          return {};
        });

      return stationData;
    }
  },
  created: function() {
    // MY WATCHING STARTS HERE  
    this.$watch(
      () => return {
        mode: this.mode,
        stationId: this.stationId,
        toDate: this.toDate,
        toTime: this.toTime
      },
      async function(data) {
        this.station = await this.getInfo({
          mode: data.mode,
          id: data.stationId,
          toDate: data.toDate,
          toTime: data.toTime
        }).then(res => {
          return res;
        });
      }
    );
  }
};
</script>
tony19
  • 125,647
  • 18
  • 229
  • 307
alexbea
  • 1,311
  • 14
  • 25

1 Answers1

3

Your watcher is returning in arrow function. It should be like:

this.$watch(
  () => {
     return {
       mode: this.mode,
       stationId: this.stationId,
       toDate: this.toDate,
       toTime: this.toTime
     }
  },

This code is invalid use:

() => return { 

Arrow function implicitly returns the value if no curly brace is used. So, you may also use like:

this.$watch(
  () => ({
     mode: this.mode,
     stationId: this.stationId,
     toDate: this.toDate,
     toTime: this.toTime
  }),

Notice, parentheses used for returning an object. You may also like to read this post further.

Bhojendra Rauniyar
  • 83,432
  • 35
  • 168
  • 231