{"action":"created","issue":{"url":"https://api.github.com/repos/strongloop/loopback/issues/1495","labels_url":"https://api.github.com/repos/strongloop/loopback/issues/1495/labels{/name}","comments_url":"https://api.github.com/repos/strongloop/loopback/issues/1495/comments","events_url":"https://api.github.com/repos/strongloop/loopback/issues/1495/events","html_url":"https://github.com/strongloop/loopback/issues/1495","id":92444733,"number":1495,"title":"Injecting Remote Context via Options","user":{"login":"ritch","id":462228,"avatar_url":"https://avatars.githubusercontent.com/u/462228?v=3","gravatar_id":"","url":"https://api.github.com/users/ritch","html_url":"https://github.com/ritch","followers_url":"https://api.github.com/users/ritch/followers","following_url":"https://api.github.com/users/ritch/following{/other_user}","gists_url":"https://api.github.com/users/ritch/gists{/gist_id}","starred_url":"https://api.github.com/users/ritch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ritch/subscriptions","organizations_url":"https://api.github.com/users/ritch/orgs","repos_url":"https://api.github.com/users/ritch/repos","events_url":"https://api.github.com/users/ritch/events{/privacy}","received_events_url":"https://api.github.com/users/ritch/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/strongloop/loopback/labels/%23tob","name":"#tob","color":"ededed"},{"url":"https://api.github.com/repos/strongloop/loopback/labels/feature","name":"feature","color":"bfe5bf"}],"state":"open","locked":false,"assignee":{"login":"ritch","id":462228,"avatar_url":"https://avatars.githubusercontent.com/u/462228?v=3","gravatar_id":"","url":"https://api.github.com/users/ritch","html_url":"https://github.com/ritch","followers_url":"https://api.github.com/users/ritch/followers","following_url":"https://api.github.com/users/ritch/following{/other_user}","gists_url":"https://api.github.com/users/ritch/gists{/gist_id}","starred_url":"https://api.github.com/users/ritch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ritch/subscriptions","organizations_url":"https://api.github.com/users/ritch/orgs","repos_url":"https://api.github.com/users/ritch/repos","events_url":"https://api.github.com/users/ritch/events{/privacy}","received_events_url":"https://api.github.com/users/ritch/received_events","type":"User","site_admin":false},"milestone":null,"comments":28,"created_at":"2015-07-01T17:47:02Z","updated_at":"2015-10-11T08:13:48Z","closed_at":null,"body":"The example below allows you to inject the remote context object (from strong remoting) into all methods that accept an `options` argument.\r\n\r\n```js\r\n\r\nfunction inject(ctx, next) {\r\n  var options = hasOptions(ctx.method.accepts) && (ctx.args.options || {});\r\n  if(options) {\r\n    options.remoteCtx = ctx;\r\n    ctx.args.options = options;\r\n  }\r\n  next();\r\n}\r\n\r\napp.remotes().before('*.*', inject);\r\n\r\napp.remotes().before('*.prototype.*', function(ctx, instance, next) {\r\n  inject(ctx, next);\r\n});\r\n\r\n// unfortunately this requires us to add the options object\r\n// to the remote method definition\r\napp.remotes().methods().forEach(function(method) {\r\n  if(!hasOptions(method.accepts)) {\r\n    method.accepts.push({\r\n      arg: 'options',\r\n      type: 'object',\r\n      injectCtx: true\r\n    });\r\n  }\r\n});\r\n\r\nfunction hasOptions(accepts) {\r\n  for (var i = 0; i < accepts.length; i++) {\r\n    var argDesc = accepts[i];\r\n    if (argDesc.arg === 'options' && argDesc.injectCtx) {\r\n      return true;\r\n    }\r\n  }\r\n}\r\n```\r\n\r\nWhy? So you can use the remote context in remote methods, operation hooks, connector implementation, etc.\r\n\r\n```js\r\nMyModel.observe('before save', function(ctx, next) {\r\n  console.log(ctx.options.remoteCtx.accessToken.userId); // current user\r\n});\r\n```\r\n\r\nThis approach is specifically designed to allow you to do what is possible with `loopback.getCurrentContext()` but without the dependency on `cls`. The injection approach is much simpler and should be quite a bit faster since `cls` adds some significant overhead.\r\n\r\n@bajtos @fabien @raymondfeng "},"comment":{"url":"https://api.github.com/repos/strongloop/loopback/issues/comments/147171604","html_url":"https://github.com/strongloop/loopback/issues/1495#issuecomment-147171604","issue_url":"https://api.github.com/repos/strongloop/loopback/issues/1495","id":147171604,"user":{"login":"ezraroi","id":5808368,"avatar_url":"https://avatars.githubusercontent.com/u/5808368?v=3","gravatar_id":"","url":"https://api.github.com/users/ezraroi","html_url":"https://github.com/ezraroi","followers_url":"https://api.github.com/users/ezraroi/followers","following_url":"https://api.github.com/users/ezraroi/following{/other_user}","gists_url":"https://api.github.com/users/ezraroi/gists{/gist_id}","starred_url":"https://api.github.com/users/ezraroi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ezraroi/subscriptions","organizations_url":"https://api.github.com/users/ezraroi/orgs","repos_url":"https://api.github.com/users/ezraroi/repos","events_url":"https://api.github.com/users/ezraroi/events{/privacy}","received_events_url":"https://api.github.com/users/ezraroi/received_events","type":"User","site_admin":false},"created_at":"2015-10-11T08:13:48Z","updated_at":"2015-10-11T08:13:48Z","body":"Also looks like it is breaking the login method, this is the error I am getting after adding the suggested code:\r\n\r\n```\r\n2015-10-11T08:05:47.393Z - error: uncaughtException: fn is not a function \r\n{ date: 'Sun Oct 11 2015 11:05:47 GMT+0300 (Jerusalem Daylight Time)',\r\n  process: \r\n   { pid: 9604,\r\n     uid: null,\r\n     gid: null,\r\n     cwd: 'c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager',\r\n     execPath: 'C:\\\\Program Files\\\\nodejs\\\\node.exe',\r\n     version: 'v4.1.2',\r\n     argv: \r\n      [ 'C:\\\\Program Files\\\\nodejs\\\\node.exe',\r\n        'c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager\\\\server\\\\server.js' ],\r\n     memoryUsage: { rss: 122175488, heapTotal: 93701632, heapUsed: 63284664 } },\r\n  os: { loadavg: [ 0, 0, 0 ], uptime: 264889.8970633 },\r\n  trace: \r\n   [ { column: 9,\r\n       file: 'c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager\\\\node_modules\\\\loopback\\\\common\\\\models\\\\user.js',\r\n       function: 'tokenHandler',\r\n       line: 228,\r\n       method: null,\r\n       native: false },\r\n     { column: 13,\r\n       file: 'c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager\\\\node_modules\\\\loopback-datasource-juggler\\\\lib\\\\relation-definition.js',\r\n       function: null,\r\n       line: 1814,\r\n       method: null,\r\n       native: false },\r\n     { column: 19,\r\n       file: 'c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager\\\\node_modules\\\\loopback-datasource-juggler\\\\lib\\\\dao.js',\r\n       function: null,\r\n       line: 320,\r\n       method: null,\r\n       native: false },\r\n     { column: 49,\r\n       file: 'c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager\\\\node_modules\\\\loopback-datasource-juggler\\\\lib\\\\observer.js',\r\n       function: 'doNotify',\r\n       line: 93,\r\n       method: null,\r\n       native: false },\r\n     { column: 49,\r\n       file: 'c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager\\\\node_modules\\\\loopback-datasource-juggler\\\\lib\\\\observer.js',\r\n       function: 'doNotify',\r\n       line: 93,\r\n       method: null,\r\n       native: false },\r\n     { column: 49,\r\n       file: 'c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager\\\\node_modules\\\\loopback-datasource-juggler\\\\lib\\\\observer.js',\r\n       function: 'doNotify',\r\n       line: 93,\r\n       method: null,\r\n       native: false },\r\n     { column: 49,\r\n       file: 'c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager\\\\node_modules\\\\loopback-datasource-juggler\\\\lib\\\\observer.js',\r\n       function: 'doNotify',\r\n       line: 93,\r\n       method: null,\r\n       native: false },\r\n     { column: 5,\r\n       file: 'c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager\\\\node_modules\\\\loopback-datasource-juggler\\\\lib\\\\observer.js',\r\n       function: 'Function.ObserverMixin._notifyBaseObservers',\r\n       line: 116,\r\n       method: 'ObserverMixin._notifyBaseObservers',\r\n       native: false },\r\n     { column: 8,\r\n       file: 'c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager\\\\node_modules\\\\loopback-datasource-juggler\\\\lib\\\\observer.js',\r\n       function: 'Function.ObserverMixin.notifyObserversOf',\r\n       line: 91,\r\n       method: 'ObserverMixin.notifyObserversOf',\r\n       native: false },\r\n     { column: 15,\r\n       file: 'c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager\\\\node_modules\\\\loopback-datasource-juggler\\\\lib\\\\observer.js',\r\n       function: 'Function.ObserverMixin._notifyBaseObservers',\r\n       line: 114,\r\n       method: 'ObserverMixin._notifyBaseObservers',\r\n       native: false } ],\r\n  stack: \r\n   [ 'TypeError: fn is not a function',\r\n     '    at tokenHandler (c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager\\\\node_modules\\\\loopback\\\\common\\\\models\\\\user.js:228:9)',\r\n     '    at c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager\\\\node_modules\\\\loopback-datasource-juggler\\\\lib\\\\relation-definition.js:1814:13',\r\n     '    at c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager\\\\node_modules\\\\loopback-datasource-juggler\\\\lib\\\\dao.js:320:19',\r\n     '    at doNotify (c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager\\\\node_modules\\\\loopback-datasource-juggler\\\\lib\\\\observer.js:93:49)',\r\n     '    at doNotify (c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager\\\\node_modules\\\\loopback-datasource-juggler\\\\lib\\\\observer.js:93:49)',\r\n     '    at doNotify (c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager\\\\node_modules\\\\loopback-datasource-juggler\\\\lib\\\\observer.js:93:49)',\r\n     '    at doNotify (c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager\\\\node_modules\\\\loopback-datasource-juggler\\\\lib\\\\observer.js:93:49)',\r\n     '    at Function.ObserverMixin._notifyBaseObservers (c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager\\\\node_modules\\\\loopback-datasource-juggler\\\\lib\\\\observer.js:116:5)',\r\n     '    at Function.ObserverMixin.notifyObserversOf (c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager\\\\node_modules\\\\loopback-datasource-juggler\\\\lib\\\\observer.js:91:8)',\r\n     '    at Function.ObserverMixin._notifyBaseObservers (c:\\\\Users\\\\rezra3\\\\Documents\\\\GitHub\\\\shutdownManager\\\\node_modules\\\\loopback-datasource-juggler\\\\lib\\\\observer.js:114:15)' ] }\r\n```\r\n\r\nI am using In-Memory connector"}}