I used an EventBus to pass the UserId to another component (UpdateStaff
). Then, I want to call an API at url/api/staffs/{UserId}
, to get the data of that particular user and bind the data to the input fields. I'm able to get the response payload but unable to bind to the input fields.
UpdateStaff.vue:
An example of an input field in the template:
<input class="input" type="text" placeholder="Username" v-model="data.username">
Data properties & created method:
data () {
return {
data: {
name: '',
username: ''
}
}
},
created () {
EventBus.$on('getUserId', (userId) => {
axios.get(staffUrl + '/' + userId)
.then((response) => {
let self = this
self.data.username = response.data.username
self.data.name = response.data.name
console.log(self.data.username)
// It prints out exactly what i want
// BUT it doesn't show the data in the input field....?
})
.catch((error) => {
console.log(error)
})
})
}
Staff.vue:
Has a vuetable component in it to display all Staffs. After clicking the Update Button, I redirect to the UpdateStaff page via calling an onActions
method.
methods: {
onActions (action, data) {
router.push({ path: '/user/UpdateStaff' })
EventBus.$emit('getUserId', action.data.userId)
}
}
Previously, I was able to display data in input fields with just axios
alone. However, after adding the EventBus
with axios
in it, I was unable to display data in input fields anymore.
How should I go about fixing this issue?
The reason you're not seeing the data update correctly is that this
is not the Vue instance when you reference it in the .then
callback.
Put the let self = this
statement at the very beginning of your created
hook to be sure you are storing the correct reference to this
:
created () {
let self = this
// after this point, `self` will reference the Vue instance even in callbacks
EventBus.$on('getUserId', (userId) => {
axios.get(staffUrl + '/' + userId)
.then((response) => {
// setting `self` to `this` here doesn't make sense because `this`
// is not refering to the Vue instance in this callback
self.data.username = response.data.username
self.data.name = response.data.name
})
.catch((error) => {
console.log(error)
})
})
}
The reason the getUserId
event isn't being handled when you push to that route is that the $emit
event is being fired before the UpdateStaff
component is created (meaning the $on
handler hasn't been set yet).
To wait for the component to have been created, wrap the $emit
in a this.$nextTick
callback:
methods: {
onActions (action, data) {
router.push({ path: '/user/UpdateStaff' })
this.$nextTick(() => {
EventBus.$emit('getUserId', action.data.userId)
})
}
}
From the documentation on the usage of Vue.nextTick
:
Defer the callback to be executed after the next DOM update cycle. Use it immediately after you’ve changed some data to wait for the DOM update.