5

I'm working on a Nativescript-Vue app, and I'm trying to use Vuex to store the hour and minute from a Timepicker to use in other Pages. I've tried catching the event with a computed property, but is there a better way of doing this with Vue?

Here's what I have:

// In NotifyTimePicker.vue (a custom Time-picking modal)
// Template:
<TimePicker row="2" col="0" colSpan="3" horizontalAlignment="center" :hour="selectedFromHour" :minute="selectedFromMinute" />

//Script
computed: {
      selectedFromHour: {
        get: function () {
          return this.$store.state.notifyFromTimeHour
        },
        set: function (newValue) {
          console.log(`Attempting to Update Store with new From Hour = ${newValue}`)
          this.$store.commit('changeNotifyFromTimeHour', newValue)
        }
      },
      selectedFromMinute: {
        get: function () {
          return this.$store.state.notifyFromTimeMinute
        },
        set: function (newValue) {
          console.log(`Attempting to Update Store with new From Minute = ${newValue}`)
          this.$store.commit('changeNotifyFromTimeMinute', newValue)
        }
      },
    },

Then, in my Vuex store:

export default new Vuex.Store({
  state: {
    notifyFromTimeHour: 9,
    notifyFromTimeMinute: 30,
  },
  mutations: {
    changeNotifyFromTimeHour (state, hour) {
      state.notifyFromTimeHour = hour
    },
    changeNotifyFromTimeMinute (state, minute) {
      state.notifyFromTimeMinute = minute
    },
  },
  actions: {

  }
});

It appears that the default values from the Store get pulled into the component just fine, but when changing the time in the picker, the 'set' part of the computed function never fires, and I never see my console.logs firing.

Should I be listening to a different change event? The documentation here doesn't go into detail on this much.

Thanks for the help!

Joe R.
  • 123
  • 11
  • Can you link to the `TimePicker` documentation? – Phil Aug 25 '20 at 03:18
  • Perhaps you could try another approach and instead of using computed properties, pull the data from the store in the created() lifecycle method and assign it to a data attribute, then add watch and watch the data attribute for changes, if it changes, then commit it to the VueX store. This gives the same behaviour and will work if you're unable to get your current approach working – Ayudh Aug 25 '20 at 03:20

1 Answers1

5

Since all props in Vue are one-way bound, the Timepicker props are only used to set initial values.

Instead, you can use a v-model binding with a computed getter and setter which reads from / writes to your store

<TimePicker
  row="2" 
  col="0" 
  colSpan="3"
  horizontalAlignment="center"
  v-model="selectedTime"
/>
export default {
  computed: {
    selectedTime: {
      get () {
        const time = new Date()
        time.setHours(
            this.$store.state.notifyFromTimeHour, 
            this.$store.state.notifyFromTimeMinute)
        return time
      },
      set (time) {
        this.$store.commit('changeNotifyFromTimeHour', time.getHours())
        this.$store.commit('changeNotifyFromTimeMinute', time.getMinutes())    
      }
    }
  }
}

Alternatively, to listen for updates, you need to use the timeChange event

<TimePicker
  row="2" 
  col="0" 
  colSpan="3"
  horizontalAlignment="center"
  :hour="selectedFromHour"
  :minute="selectedFromMinute"
  @timeChange="changeTime"
/>
import { mapState } from "vuex"

export default {
  computed: mapState({
    selectedFromHour: "notifyFromTimeHour",
    selectedFromMinute: "notifyFromTimeMinute"
  }),
  methods: {
    changeTime (payload) {
      // documentation doesn't say what the event payload is, let's assume it's a Date
      this.$store.commit('changeNotifyFromTimeHour', payload.getHours())
      this.$store.commit('changeNotifyFromTimeMinute', payload.getMinutes())
    }
  }
}
Phil
  • 157,677
  • 23
  • 242
  • 245
  • Thank you, sir. Using the v-model route worked. I had issues using the @timeChange event for some reason, kept getting errors around 'payload' being converted to a circular JSON structure. – Joe R. Aug 25 '20 at 12:06
  • The documentation is sorely lacking information about event payloads. I'm glad the v-model option worked for you – Phil Aug 25 '20 at 13:41