I am trying to extend find()
method for a service named properties
in my FeathersJS app.
What I need is appending in all records returned by find()
an array with integers coming from another service named propertyadds
. This means I need to change my response from
{
"total": 2973,
"limit": 10,
"skip": 0,
"data": [
{
"id": 1,
...
},
{
"id": 2,
...
}
...
]
}
to
{
"total": 2973,
"limit": 10,
"skip": 0,
data: [
{
"id": 1,
...
"additionals": [10,20,30]
},
{
"id": 2,
...
"additionals": [12,25,33]
}
...
]
}
where the values in additionals come from service propertyadds
, which manages a table like
| property_id | additional_id |
|-------------|---------------|
| 1 | 10 |
| 1 | 20 |
| 1 | 30 |
| 2 | 12 |
| 2 | 25 |
| 2 | 33 |
|-------------|---------------|
My initial idea was extending properties
service like this
const { Service } = require('feathers-sequelize');
exports.Properties = class Properties extends Service {
async find(data,params) {
let newResponse = await super.find(data,params);
let newData = newResponse.data.map(async pr => {
pr.additionals = await app.service('propertyadds').find({
properti_id: pr.id
})
return pr;
})
return {
total: newResponse.total,
limit: newResponse.limit,
skip: newResponse.skip,
data: newData
}
}
};
The problem is I don't have app
inside src/services/properties/properties.class.js
and (being new to FeathersJS as I am) I don't know how to get it.
What do I need to have a valid app
const accessing all services inside this module?
The solution was, in fact, achieved when I visited src/services/properties.service.js
and found out this line
app.use('/properties', new Properties(options, app));
So, service properties
was, in fact, receiving an app
object in its creation.
Learning this made me see the correct solution, written in src/services/properties/properties.class.js
like this:
const { Service } = require('feathers-sequelize');
exports.Properties = class Properties extends Service {
constructor(options, app) {
super(options, app);
this.app = app;
}
async find(data, params) {
let oldRes = await super.find(data, params);
let newResData = oldRes.data.map(async pr => {
let includedRecords = await this.app.service('propertyadds').find({
query: {
property_id: pr.id
}
})
pr.additionals = includedRecords.map(e => e.additional_id).sort();
return pr;
})
return await Promise.all(newResData)
.then(completed => {
return {
total: oldRes.total,
limit: oldRes.limit,
skip: oldRes.skip,
data: completed
}
})
}
}
As it may be seen, it was a matter of creating a constructor
method for the extended Properties class, in order to expose the app
object in this.app
. This may be done after calling super(options,app)
to make this
available.
After this it was just a matter of using this.app
to create an instance of the other service and then making the correct async calls.