One such example would be deleteById, where instead of deleting, i would set only deleted property.
+1
For example, if you want to override it for customer model in 2.x, add a customer.js to common/models:
module.exports = function(Customer) {
Customer.deleteById = function(id, cb) {
Customer.update({id: id}, {deleted: true}, cb);
}
}
Nice, thanks
I have created a dynamic model "Item" (item.json). I want to override the "find" method. I wrote the following in item.js
module.exports = function(Item) {
Item.find = function(cb) {
cb(null, 'This is a overridden method');
}
}
But I don't get the message passed in the callback function when I access the method from explorer. Is there anything else I need to do here.
@alffrey I think your find method signature is wrong (it should take a query argument too). Other than that, it should work. I have a project where I'm doing this, and it works for me.
@fabien I changed my method signature to "Item.find = function (params, cb)" but still no luck.
@alffrey perhaps try cb(new Error('Override')) to see if the method is being called, perhaps it's tripping over the string return value you're giving.
@fabien The overridden method is not getting called at all. I even tried putting in a console.log statement inside the method and it is not getting executed. From the explorer I am hitting GET /Items method.
@alffrey I just tried this in a /models/*.js specifically with a find method like yours, and it works. I'd need more details in order to help you solve this.
@alffrey Maybe this is what you want.
Model.once('attached',function(){
Model.find = function(filter,cb){
cb(null,'This is a overridden method')
}
})
@veekungx Thank you so much. Your solution works.
I have similar issue.
https://github.com/strongloop/loopback/issues/1745
@veekungx's solution works for me, @raymondfeng's didn't.
I was trying @veekungx's solution but server got really slow, at the end it didn't complete any request. I found out debugging that Model.on('attached'.... was being called constantly again and again. Am I doing something wrong?
@raymondfeng's didn't work for me
Thanks
Edit: Ok never mind is an issue with promises inside Model.on('attached'
The @veekungx example doesn't work as it is for me (2.22.0). this works :
User.on('attached',function(app){
User.find = function(filter, empty, cb){
cb(null,['This is a overridden method'])
}
})
EDIT:
Since LB uses find() to login, you have to send a User instance to the callback. Otherwise :
Error in POST /Users/login: TypeError: user.hasPassword is not a function
EDIT:
Surfer.__unlink__friends = function (id, cb) {
console.log(, id, cb)
}
This new code above doesn't trigger.
strong-remoting:shared-method - __unlink__friends - invoke with +1ms [ 1, [Function: callback] ]
loopback:connector:postgresql SQL: DELETE FROM "couch-surfing"."surfer-friend" WHERE "surferid"=$1 AND "friendid"=$2
I found overriding the find method also affected findOne etc which was undesirable.
My workaround was:
// Override Project.find to use our bespoke Project.list
Project.on('attached', () => {
const origFind = Project.find.bind(Project);
Project.find = (query, options, cb) => {
if (typeof options === 'function' && options.name === 'callback') {
return Project.list(query, options);
}
return origFind(query, options, cb);
};
});
// This method is written as it would be as a standard remote method
Project.list = (filter, cb) => {
...
}
I tried this for updateAttributes with no success.
Workaround: disable method and create my own
Important: I no longer use or recommend the solution below - see my next comment
My solution required a little tweaking for findById, and the same is probably true for updateAttributes @mamartins
I now have a module exposing an overideRemoteMethod function:
function overideRemoteMethod (model, methodName, newFunc) {
const origFunc = model[methodName];
model[methodName] = (a, b, c, d) => {
// We rely on the remote method call having a different signature to
// the standard call.
switch (methodName) {
case 'findById':
if (typeof c === 'function' && c.name === 'callback') {
return newFunc(a, b, {}, c);
}
return origFunc.call(model, a, b, c, d);
case 'find':
case 'count':
default:
if (typeof b === 'function' && b.name === 'callback') {
return newFunc(a, {}, b);
}
return origFunc.call(model, a, b, c);
}
};
}
(You'll probably need to add case 'updateById' below case 'findById')
I then call it in my model:
module.exports = (Workspace) => {
Workspace.on('attached', () => {
// Overide default methods to only return workspaces that the given user has
// access to
overideRemoteMethod(Workspace, 'find', Workspace.remoteFind);
overideRemoteMethod(Workspace, 'count', Workspace.remoteCount);
overideRemoteMethod(Workspace, 'findById', Workspace.remoteFindById);
...
}
Workspace.remoteFind = function (filter, options) {
...
}
That's a good one.
It would be good to have a default way of doing this for all methods
Try Model.once('attached') as opposed to Model.on('attached') ...otherwise memory leaks
My above solution for overriding methods is flawed as it doesn't provide a way to get the current context (now that getCurrentContext is deprecated).
Our solution has instead been to simply disable the default methods and create new ones. For clarity and consistency, we always name them remoteFind, remoteCount, etc. and we always pass in context as the first accepts arg.
Lets add something like this:
Model.once('attached',function(){
Model.find = function(filter,cb){
cb(null,'This is a overridden method')
}
})
to the docs.
See also #1028
how can I disable the filter paramter this way? for my GET /api/entity endpoints I would like to disable the filter parameter
just figured it out, its possible to just override by rebinding to the http path:
Model.remoteMethod('findById', {
description: 'Find a model instance by {{id}} from the data source.',
accessType: 'READ',
accepts: [
{
arg: 'id', type: 'any', description: 'Model id', required: true,
http: {source: 'path'}
},
{arg: 'options', type: 'object', http: 'optionsFromRequest'},
],
returns: {arg: 'data', type: 'Model', root: true},
http: {verb: 'get', path: '/:id'}
});
override remote method and override model method is different, guys!
findById, then you go too far, 'cause when you are using this method anywhere, you are using the new rewrite version which I think is not expect behavior.@ChopperLee2011 I know that its different, I'd also agree that overriding the model method usually has a lot of implications, in my case it was sufficient to override just the remote method, since i only wanted to remove the filter attribute :)
I've tried @veekungx solution too, but it seems to work as an override, but it shows me the error message: TypeError: cb is not a function
+1 @Maransatto Same for me
@here i am trying to override the deleteById Method to support my need but it seems not working
MyModel.once('attached', function () {
MyModel.deleteById = function (id, cb) {
console.log('Overridden the models deleteById remoted method');
console.log(id);
MyModel.update({'id': id}, {'deleted': true}, cb);
}
});
In case if any body tries to do that in future here is how i did it(complete MyModel file)
'use strict';
module.exports = function (MyModel) {
MyModel.once('attached',function(){
MyModel.deleteById = function(filter,auth, cb){
cb(null,'This is a overridden method')
}
})
};
Thing to note here is that cb is the third argument to deleteById
Hello, we don't have bandwidth to describe the solution(s) outlined above in our docs, but we are happy to help you along the way if you decide to contribute such documentation. See https://loopback.io/doc/en/contrib/doc-contrib.html to get started.
In LoopBack 4, all REST API methods are code-generated as thin wrappers around the underlying Repository data-access API and can be directly edited by app developers.
Hi,
Can somebody give me the syntax for overriding patchAttributes method for a model.I have overidden all other methods but facing issue with it
@seshagiri13 You can always add a beforeRemote that captures everything using the . wildcard. Then add a breakpoint in your debugger, trigger the request you want to override, and inspect what the Context object has. The context object has a bunch of information related to the request, including the "name" loopback assigns it internally. You can use that to override it. Like so:

Most helpful comment
@alffrey Maybe this is what you want.