Eleina Nieborg
Eleina Nieborg

Reputation: 33

Vuejs 2 assign data to variable with event received data from eventbus

I am creating a small client-side Vuejs application and have a bit of trouble with assigning data to a variable. In a login component I am emitting user data with an eventBus, and in an index component I receive the data from the eventbus within the mounted: function (). I have no trouble with receiving the data, but what I would like to do is assign this received data to the currentUser variable. This is what I have in the index component:

mounted: function () {
    eventBus.$on('thisEvent', function (userObject) {
        console.log('event received!', userObject)
        this.currentUser = userObject.user
        console.log('The user: ', this.currentUser) // Shows correct new user data
    }.bind(this))
    console.log('User outside eventbus:', this.currentUser) // Shows empty user
}

And this is how the user looks like in the data:

data: function () {
  return {
     currentUser: {
     firstname: '',
     lastname: '',
     last_login: ''
    }
  }
}

I cannot figure out why the currentUser is emptied outside the eventbus. Thanks in advance!

**Edit: ** This is how I have it now in my index.vue

**Edit 2: ** This shows the output of the console logs. The left one shows the user object in the eventBus, the right one shows the console.log(this) outside the eventBus, with empty currentUser object

This is the $emit of the eventBus, this is being called when the get request response is successfull. The code is in the login.vue, where an authenticated user object gets filled, and transfers this data to the index.vue.

eventBus.$emit('thisEvent', { user: this.user })

Upvotes: 3

Views: 2683

Answers (2)

Amresh Venugopal
Amresh Venugopal

Reputation: 9549

Using an arrow function would help you as it doesn't bind its own context.

mounted: function () {
  eventBus.$on('thisEvent', (userObject) => {
    console.log('event received!', userObject)
    this.currentUser = userObject.user
    console.log('The user: ', this.currentUser)
  })
  console.log('User outside eventbus:', this.currentUser)
}

another way: (If you're not using babel or want to support browsers without ES6 support)

mounted: function () {
  var self = this
  eventBus.$on('thisEvent', function (userObject) {
    console.log('event received!', userObject)
    self.currentUser = userObject.user
    console.log('The user: ', self.currentUser)
  })
  console.log('User outside eventbus:', self.currentUser)
}

EDIT

The code in the question and the solutions posted in the thread work just fine. The output that you see is perfectly normal.

mounted: function () {
  eventBus.$on('thisEvent', function (userObject) {
    console.log('event received!', userObject)
    this.currentUser = userObject.user
    console.log('The user: ', this.currentUser) // Shows correct new user data
  }.bind(this))
  console.log('User outside eventbus:', this.currentUser) // Shows empty user
}

The mounted lifecycle hook is called when the component's template and data is ready and rendered.

(You could do the same thing in the created hook as what you have done in mounted)

So

console.log('User outside eventbus:', this.currentUser)

gets logged before your eventBus emits an event.

you can easily check this using a watch like so:

watch: {
  currentUser(newValue, oldValue) {
    console.log(newValue, oldValue)
  }
}

Here is a working jsfiddle

Upvotes: 1

Marek Urbanowicz
Marek Urbanowicz

Reputation: 13644

I cannot figure out why the currentUser is emptied outside the eventbus.

Because of the this scope. Inside classic function syntax you are binding this from function. Use arrow function shown below and it will work as it does not bind this so this.currentUser will update your component data, not just function data.

mounted: function () {
    eventBus.$on('thisEvent', (userObject) => {
        console.log('event received!', userObject)
        this.currentUser = userObject.user
        console.log('The user: ', this.currentUser) // Shows correct new user data
    })
    console.log('User outside eventbus:', this.currentUser) // Shows empty user
}

If above somehow not working, try this solution:

mounted: function () {
        let _self = this;
        eventBus.$on('thisEvent', (userObject) => {
            console.log('event received!', userObject)
            _self.currentUser = userObject.user
            console.log('The user: ', _self.currentUser) // Shows correct new user data
        })
        console.log('User outside eventbus:', _self.currentUser) // Shows empty user
    }

Upvotes: 0

Related Questions