feathers
feathers copied to clipboard
Client socket event listeners do not run hooks.
Expected behavior
When listening to a socket event, I expect the returned data to have been run through all client side after hooks.
Actual behavior
The data is returned before being passed through all hooks.
Repo and Instructions
Please see this repo https://github.com/DaddyWarbucks/feathers-client-socket-hooks
The app starts up a memory service and creates a thing on app startup.
Open your browser to http://localhost:3030/ and open the console.
Note the console.logs and inspect the code at src/public/index.html, specifically lines 90-112
Putting it here as well for visbility: The technical reason why this is not happening at the moment is that a service can say “I’m taking care of these events myself” (instead of letting Feathers handle it). That’s what the client side websocket services do and then they just listen to the socket events and emit it with the same data as their own (if it belongs to that service).
It’s a very similar issue to something I’ve been trying (and failing) to do with RethinkDB (where events come from the db changefeed instead of a websocket): https://github.com/feathersjs-ecosystem/feathers-rethinkdb/issues/76
Behavior should be symmetric on client and server because we all claim that Feathers is isomorphic. So if we expect the after hooks to have been run when we listen to an event on the server-side the same should apply on the client side IMHO.
Technically this is isomorphic behaviour. If your server side service defines its own events Feathers will not mess with any of the data. This allows to override default events (created, updated etc.) as well which is what the client services are using.
Thinking about it yesterday, we could add a hooks flag or something that, instead of just emitting the event directly, calls the service method with context.result set (so that the server call gets skipped).
What this would mean is that when a <servicename> created event with data comes in, instead of calling service.emit('created', data) it would call service.create(data), run through all hooks (but not make the server call) and then send the internal created event with the final result from that call.
For custom events you are right, you can actually emit them whenever you want (even before running all hooks), but according to the docs about service events: Events are not fired until all of your hooks have executed.. So on the client side I expect the after hooks to be run before getting the patched event or do I miss the point ?
About calling the service this will trigger before hooks doesn't it ? If so this is not expected behavior I guess...
True, the docs should be more specific there. Basically if a service chooses to send their own events they will have to take care of it themselves.
And yes, it will trigger before hooks. As the issue watching RethinkDB changefeeds, just going through the after hooks may cause more issues than it solves. For example, you won't get much of the information you'd expect in the hook context (provider, user) because just taking the data from an event does not have it. Ideally, a solution would also take https://github.com/feathersjs/feathers/issues/932 into account to be future proof.