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!

2
  • Can you link to the TimePicker documentation? Commented Aug 25, 2020 at 3: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 Commented Aug 25, 2020 at 3:20

1 Answer 1

5
+50

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())
    }
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

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.
The documentation is sorely lacking information about event payloads. I'm glad the v-model option worked for you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.