users.hook.js
const { lowerCase, alterItems } = require('feathers-hooks-common')
const acd = require('../../hooks/acd')
module.exports = {
before: {
all: [],
find: [],
get: [],
create: [lowerCase('mail'), acd()],
update: [lowerCase('mail')],
patch: [lowerCase('mail')],
remove: []
},
...
acd.js
// Use this hook to manipulate incoming or outgoing data.
// For more information on hooks see: http://docs.feathersjs.com/api/hooks.html
// eslint-disable-next-line no-unused-vars
module.exports = function (options = {}) {
return async context => {
context.service.emit('customEvent', { id_room: "xi2undj383828823xej3" });
};
};
channels.js (Authentication disabled only for test purpose)
module.exports = function(app) {
if(typeof app.channel !== 'function') {
return;
}
app.on('connection', connection => {
app.channel('anonymous').join(connection);
});
app.on('login', (authResult, { connection }) => {
if(connection) {
// The connection is no longer anonymous, remove it
app.channel('anonymous').join(connection);
// Add it to the authenticated user channel
app.channel('authenticated').join(connection);
}
});
// eslint-disable-next-line no-unused-vars
app.publish((data, hook) => {
return app.channel('anonymous');
// return app.channel('authenticated');
});
};
I expect server emit the custom event to client side, when a new user is created.
Don't execute emit event in hook service, the client side only receive the added user.
Scripts used in client side, obtained from here:
Modular@feathersjs/client
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/core-js/2.1.4/core.min.js"></script>
<script src="//unpkg.com/@feathersjs/client@^3.0.0/dist/feathers.js"></script>
<script src="//unpkg.com/[email protected]/dist/socket.io.js"></script
// Create user with Webscoket
users.create({
"email": Math.floor(Math.random() * 109384023)+"[email protected]", //required
"client_id": "5c6b4066bac35a6658024b1f" //required
})
// Listener created and custom event
users.on('created', (message) => {
console.log("New user created: " + message)
})
users.on('customEvent', (message) => {
console.log("Custom event log: " + message)
})
{
"db": "mongodb",
"framework": "mongoose"
}
Module versions (especially the part that's not working):
$ npm info @feathersjs/cli version
3.9.0
NodeJS version:
$ node -v
v10.13.0
Module Loader:
@feathersjs/cli
As documented in the Custom events API, the service also needs to include the custom events it wants to publish to clients in an events array when it is registered.
@daffl you have a example of that?
If I'm not wrong, I need to publish the custom events in channels.js?
The API has an example for a custom service. Existing database adapters use the events option.
Your channel settings will publish all events automatically (but only for the ones that have the events option set).
I understand more! I need use this adapters in my case for example:
In app.js
const service = require('feathers-mongoose');
// Enable Socket.io services
app.configure(socketio());
// Connect to the db, create and register a Feathers service.
app.use('/my-service', service({
events, //How put the events here??? <-------------------------
paginate: {
default: 10,
max: 50
}
}));
Sorry, I'm really confused :anguished:, the events parameter goes like this? :sweat_smile:
const events = [
service.emit('customEvent', { status: 'completed' }),
service.emit('otherCustomEvent', { status: 'incomplete' })
]
Really thanks for your help! :grin:
It's an array of event names just like the example of the custom service class:
// Connect to the db, create and register a Feathers service.
app.use('/my-service', service({
events: [ 'customEvent' ],
paginate: {
default: 10,
max: 50
}
}));
Now app.service('my-service').emit('customEvent') will be published to all clients in channels that have been configured (anonymous) in your case.
Thanks @daffl ! :blush:
It's an array of event names just like the example of the custom service class:
// Connect to the db, create and register a Feathers service. app.use('/my-service', service({ events: [ 'customEvent' ], paginate: { default: 10, max: 50 } }));Now
app.service('my-service').emit('customEvent')will be published to all clients in channels that have been configured (anonymous) in your case.
@daffl I try start feathers with this configuration in app.js
const service = require('feathers-mongoose');
const usersModel = require('./models/users.model'); // <---------- Load model
app.use('/users', service({
usersModel, // <---------------------- Here is the model :(
events: ['yourTurn']
}));
users.model.js
// users-model.js - A mongoose model
//
// See http://mongoosejs.com/docs/models.html
// for more of what you can do here.
module.exports = function (app) {
const mongooseClient = app.get('mongooseClient');
const { Schema } = mongooseClient;
const users = new Schema({
firstname: {
type: String,
required: true
},
lastname: {
type: String,
required: true
},
mail: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true,
select: false
},
disabled: {
type: Boolean,
default: false
},
status: {
connected: {
type: Boolean,
default: false
},
available: {
type: Boolean,
default: false
}
},
client_id: {
type: mongooseClient.Schema.Types.ObjectId,
ref: 'accounts',
required: true
}
}, {
timestamps: true
});
return mongooseClient.model('users', users);
};
log
C:\xampp\htdocs\api-feathers\node_modules\feathers-mongoose\lib\service.js:11
throw new Error('You must provide a Mongoose Model');
^
Error: You must provide a Mongoose Model
at new Service (C:\xampp\htdocs\api-feathers\node_modules\feathers-mongoose\lib\service.js:11:13)
at init (C:\xampp\htdocs\api-feathers\node_modules\feathers-mongoose\lib\service.js:333:10)
at Object.<anonymous> (C:\xampp\htdocs\api-feathers\src\app.js:45:19)
at Module._compile (internal/modules/cjs/loader.js:688:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:699:10)
at Module.load (internal/modules/cjs/loader.js:598:32)
at tryModuleLoad (internal/modules/cjs/loader.js:537:12)
at Function.Module._load (internal/modules/cjs/loader.js:529:3)
at Module.require (internal/modules/cjs/loader.js:636:17)
at require (internal/modules/cjs/helpers.js:20:18)
at Object.<anonymous> (C:\xampp\htdocs\api-feathers\src\index.js:3:13)
at Module._compile (internal/modules/cjs/loader.js:688:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:699:10)
at Module.load (internal/modules/cjs/loader.js:598:32)
at tryModuleLoad (internal/modules/cjs/loader.js:537:12)
at Function.Module._load (internal/modules/cjs/loader.js:529:3)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start: `node src/`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging
output above.
What am I doing wrong? :sob: Because I load the model created with CLI feathers generate service
You changed the model property name. The property when initializing the service has to be called Model:
app.use('/users', service({
Model: usersModel,
events: ['yourTurn']
}));
You changed the model property name. The property when initializing the service has to be called
Model:app.use('/users', service({ Model: usersModel, events: ['yourTurn'] }));
@daffl sorry, for the stupid error, but this don't resolve the problem :sob:
const service = require('feathers-mongoose');
const usersModel = require('./models/users.model');
app.use('/users', service({
Model: usersModel,
events: ['yourTurn']
}));
If I understand, the error say me that the model I required users.model.js is not Moongose Model?
users.model.js
// users-model.js - A mongoose model
//
// See http://mongoosejs.com/docs/models.html
// for more of what you can do here.
module.exports = function (app) {
const mongooseClient = app.get('mongooseClient');
const { Schema } = mongooseClient;
const users = new Schema({
firstname: {
type: String,
required: true
},
lastname: {
type: String,
required: true
},
// .... Blablabla
}, {
timestamps: true
});
return mongooseClient.model('users', users);
};
The code above _should_ work. If you are having trouble with this, try regenerating the service (or create a new one) and _only_ add the events: [ 'somethin' ] property in the myservice.service.js file. Don't change anything else.
@daffl perfect, thanks!!!
If use CLI, go to myservice.service.js locted in ./services/myservices/myservice.service.js and in the options variable:
myservice.service.js
const options = {
Model,
events: ['customEvent'],
paginate
};
channels.js
app.service('myservice').emit('customEvent', { data: "customdata" });