DEV Community

Matt Chaffe
Matt Chaffe

Posted on • Originally published at Medium on

3 2

FeathersJS Emitting

Photo by rawpixel on Unsplash

FeathersJS makes it really easy to write realtime web API’s. I want to talk about how you can emit data from your hooks. I had an application which had two services groups and group-access , a user could only fetch items from groups if they had a record in the group-access collection.

But what this meant was when a user was granted access via the group-access service they would have to reload the page in order to re-fetch groups to reflect the new access.

create: [
async context => {
const { app, data, params } = context
// Exit if no provider
// only run for external access
if (!params.provider) {
return context
}
// Load the group so we can emit this value to the client
const group = await app.service('groups').get(data.groupId, context.params)
if (group) {
// Emit a created event, so we can publish this to the user
const service = app.service('groups')
await service.emit('created', group, Object.assign({}, context, { path: 'groups', hookEmit: true, userId: data.userId }))
}
}
]
view raw hooks.js hosted with ❤ by GitHub

The above snippet is for an after create hook, this would be for the group-access service. When a new group-access record is created this hook will run and will load the group via a get, so we can emit this record. We then emit on the groups service and use the created event name. We clone the context and add some additional params so that we can use these within the groups publish function.

Be sure to update the path so that it will emit using that path / service name.

service.publish((data, context) => {
// Only publish if we are from an internal emit
// Only publish the new record to the user within the context
if (context.hookEmit) {
return app.channel(app.channels)
.filter(connection => connection.user && connection.user._id.toString() === context.userId.toString())
.send(data)
}
})
view raw service.js hosted with ❤ by GitHub

In the above publish snippet, we are only going to publish realtime data if we have come from an internal emit, we can verify this by checking the property we added to the context in the emit call. In a real app you would probably be emitting based on some other checks.

What this will do is filter all the channels to only that of context.userId which was passed in by the custom emit. It will send that data to the channel.

If you are using something like can-connect-feathers or feathers-vuex when a realtime created event happens the created item will be added to the list of groups and should be displayed automagically.

This should be done the same for the removed event, so when a groups-access record is deleted, as such revoking the user access. We can emit a removed event, which if configured the client will be listening for, thus removing the record from the list.

Thanks for reading.

If you noticed anything incorrect or that could be improved please comment below. I appreciate all constructive feedback.

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs