Reputation: 11
I'm new to Vue.js 2 and am building my first (vue) web application. The application uses two components, one header component and one login component. When the login is succesfull a "loggedIn"-flag variable will be toggled in a singleton authentication service. This service is responsible to emit an event to the header component (and maybe other listening components) to notify that the user is logged in. The header in turn should update it's view and display the username.
Everything works as described, events are generated and emitted/received using a global event bus. However, when the event is received by the header component it's unable to update the view.
I already tried different approaches: basic subscriber pattern, vuex and now the event bus. Nothing seems to work. Does anyone know what the problem might be?
EventBus.js:
import Vue from 'vue'
var eventBus = new Vue()
export default eventBus
SessionService.js
import eventBus from '../util/EventBus'
class SessionService {
loggedIn=false
constructor () {
if (this.isValid(this.getSessionToken())) {
this.loggedIn = true
}
}
setSessionToken (token) {
localStorage.setItem('token', token)
if (this.isValid(token)) {
eventBus.$emit('LOGGEDIN')
} else {
eventBus.$emit('LOGGEDOUT')
}
}
getSessionToken () {
return localStorage.getItem('token')
}
isValid (token) {
return token !== undefined && token != null && token !== ''
}
}
var sessionService = new SessionService()
export default sessionService
Header.vue: Script
import eventBus from '../../services/util/EventBus'
var loggedIn = false
var m = this
eventBus.$on('LOGGEDIN', function () {
console.log('RECEIVED')
m.loggedIn = true
})
export default{
name: 'Header',
data () {
return {loggedIn}
}
}
Header.vue: HTML
<template>
<div>
<nav class="navbar navbar-expand-lg ap-top-nav">
<div class="container" >
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<form class="form-inline my-2 my-lg-0 mr-auto">
<div class="ap-searcher">
<input class="ap-search" type="text" placeholder="Search" aria-label="Search"/>
<i class="fa fa-search"></i>
</div>
</form>
<div class="logo ml-auto mr-auto">
<img src="../../assets/images/logo.png"/>
</div>
<ul class="navbar-nav ml-auto">
<li class="nav-item ap-button blue wide">
<router-link to="/login">Login: {{loggedIn}}</router-link>
</li>
<li class="nav-item ap-button light-blue wide">
<router-link to="/registration">Register</router-link>
</li>
<li class="nav-item ap-button blue-border">
<a href="#">EN <i class="fa fa-sort-desc" aria-hidden="true"></i></a>
</li>
</ul>
</div>
</div>
</nav>
<nav class="navbar navbar-expand-lg ag-bottom-nav">
<div class="container">
<div class="collapse navbar-collapse " id="navbarNav">
<ul class="navbar-nav ml-auto">
<li class="nav-item active">
<router-link class="nav-link ap-link" to="/">Auctions</router-link>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Lots</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Organize your own auction</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Contact </a>
</li>
</ul>
</div>
</div>
</nav>
<div class="ap-line">
</div>
</div>
</template>
Upvotes: 1
Views: 1708
Reputation: 316
Old, But the answer is '=>' ARROW_Function
eventBus.$on('LOGGEDIN', (playload)=>{
console.log('RECEIVED')
self.loggedIn = true
})
Upvotes: 0
Reputation: 55644
In your Header.vue
component, when you are registering the 'LOGGEDIN'
listener, you are trying to access the Vue instance via this
outside the scope of the Vue instance.
Move that logic inside the created
hook of the component so that the eventBus
listener is still registered when the component is instantiated, but so that this
is referencing the Vue instance:
import eventBus from '../../services/util/EventBus'
export default {
name: 'Header',
data() {
return { loggedIn: false }
},
created() {
let self = this;
eventBus.$on('LOGGEDIN', function () {
console.log('RECEIVED')
self.loggedIn = true
})
}
}
Upvotes: 3
Reputation: 1580
You have some weird structure of Header component code, but I think it should be like this:
export default{
name: 'Header',
data () {
return { loggedIn: loggedIn }
}
}
Upvotes: 0