Vue.js Event Bus + Promises

Event Bus messages in Vue.js is a powerful ability that allows for non parent/child components to communicate. It is usually a perfect solution when 1 way communication is needed.

Recently, I needed the same ability to send a message to a listening $on() and after some work send the result back to the $emit() caller, but Vue.js does not have a built in way to do that. In my case I had a database in the main process to which I needed to control access to.

This example uses the Lovefield database.

Using Promises it is possible to create the desired functionality.

Main.js

var db = new Database()
var dbReady = false
EventBus.$on(‘dbDoAction’, (data, resolve, reject) => {
if (dbReady) {
db.handleAction(data, resolve, reject)
} else {
// add job to a queue
}
})
db.init().then(() => {
dbReady = true
})

Users.js

let prms = new Promise((resolve, reject) => {
var data = {
action: ‘getUser’,
id: 10
}
EventBus.$emit(‘doAction’, data, resolve, reject)
})
prms.then((res) => {
// use res
}).catch((err) => {
// handle error
})

Database.js

class Database {
constructor () {
this.db = null
this.databases = {
users: null
}
}

init () {
var s = schemas.getSchemas()
return s.connect().then((db) => {
this.db = db
this.databases.users = db.getSchema().table(‘users’)
})
}
doAction (data, resolve, reject) {
if (typeof this[data.action] !== ‘function’) {
reject(`Database class function does not exist: ${data.action}`)
} else {
this[data.action](data).then((res) => {
resolve(res)
}).catch((err) => {
reject(err)
})
}
}

getUser (data) {
return this.db.select()
.from(this.databases.users)
.where(this.databases.users.id.eq(data.id))
.exec()
}
}

Obviously you are going to want to add a queue system for actions in the case that the database is not yet ready. Schemas are defined the same as on the Lovefield examples.

Conclusion

Although Vue.js does not have built in support to send messages back to Event Bus emitters, it is simple to add the functionality with Promises. Or if you feel like it, you could also implement a callback design.

If you found this post useful, check out my personal website where I will continue my writing on https://jsgv.io