loopback remote connector does not support relations

Created on 1 Aug 2014  路  21Comments  路  Source: strongloop/loopback

I was playing with browserify, because i wanted to generate api for my app, but relations does not seem to work.

bug

Most helpful comment

I think I'm experiencing the same issue. I'm following this doc in an API with a container and I have an error when I add relations to my container model.

{
  "name": "Container",
  "base": "PersistedModel",
  "properties": {
    "name": {
      "type": "string"
    }
  },
  "validations": [],
  "relations": {},
  "acls": [],
  "methods": {}
}

Here's my container.json and here's the error :

TypeError: Cannot call method 'call' of undefined
    at EventEmitter.<anonymous> (/home/mowso/Documents/loopback-examples/test/node_modules/loopback-datasource-juggler/lib/datasource.js:434:37)
    at EventEmitter.g (events.js:180:16)
    at EventEmitter.emit (events.js:95:17)
    at DataSource.setupDataAccess (/home/mowso/Documents/loopback-examples/test/node_modules/loopback-datasource-juggler/lib/datasource.js:540:14)
    at DataSource.attach (/home/mowso/Documents/loopback-examples/test/node_modules/loopback-datasource-juggler/lib/datasource.js:752:8)
    at Function.ModelClass.attachTo (/home/mowso/Documents/loopback-examples/test/node_modules/loopback-datasource-juggler/lib/model-builder.js:336:16)
    at Registry.configureModel (/home/mowso/Documents/loopback-examples/test/node_modules/loopback/lib/registry.js:238:15)
    at configureModel (/home/mowso/Documents/loopback-examples/test/node_modules/loopback/lib/application.js:441:16)
    at EventEmitter.app.model (/home/mowso/Documents/loopback-examples/test/node_modules/loopback/lib/application.js:133:5)
    at /home/mowso/Documents/loopback-examples/test/node_modules/loopback-boot/lib/executor.js:190:9

Any ideas :grin: ?

All 21 comments

Would you please provide more details?

@ritch Any insights?

Ok, so i get error here(Uncaught TypeError: Cannot read property 'call' of undefined): https://github.com/strongloop/loopback-datasource-juggler/blob/master/lib/datasource.js#L447 because belongsTo operation on remote data source is not defined(modelClass gets datasource operations mixed in from dao, but remote dao there seems to be no operation defined, here: https://github.com/strongloop/loopback/blob/master/lib/connectors/remote.js#L39). This makes remote client with relations defined unusable.

I would really like to use loopback remote client for accesing my api, and it might be the case i have done something wrong, but that's what i've deduced from debugging.

I think it's a good use case. I'll leave it to @ritch to help you configure the remote data source

It might be also the case that i also misunderstood remote data source, but what i've expected is to able to use all methods on models as locally. I can see in fullstack example that you've been using replication, but what i mostly need is queries on models themselves or on related models.

Also the stacktrace:

TypeError: Cannot call method 'call' of undefined
    at DataSource.defineRelations (/home/offlinehacker/projects/loopback-datasource-juggler/lib/datasource.js:447:28)
    at DataSource.setupDataAccess (/home/offlinehacker/projects/loopback-datasource-juggler/lib/datasource.js:483:8)
    at DataSource.attach (/home/offlinehacker/projects/loopback-datasource-juggler/lib/datasource.js:694:8)
    at Function.ModelClass.attachTo (/home/offlinehacker/projects/loopback-datasource-juggler/lib/model-builder.js:281:16)
    at Object.registry.configureModel (/home/offlinehacker/projects/loopback/lib/registry.js:173:15)
    at configureModel (/home/offlinehacker/projects/loopback/lib/application.js:401:12)
    at Function.app.model (/home/offlinehacker/projects/loopback/lib/application.js:139:5)
    at /home/offlinehacker/projects/euganke_master/app_new/node_modules/loopback-boot/lib/executor.js:136:9
    at Array.forEach (native)
    at setupModels (/home/offlinehacker/projects/euganke_master/app_new/node_modules/loopback-boot/lib/executor.js:132:23)

and example definition of model:

{
  "name": "user",
  "base": "User",
  "emailVerificationRequired ": true,
  "relations": {
    "memberships": {
      "model": "groupMember",
      "type": "hasMany",
      "foreignKey": "userId"
    }
  }
}

I'm guessing the remote connector is not properly handling the relations mixin. In theory, as long as the mixins are added - the code should call the correct remote method.

Ill take a deeper look at this...

I dug around and tracked it down to the DAO being an empty function within the DataSource.prototype.mixin method of datasource.js. I added the following line to the DataSource.prototype.attach method and it got rid of the error:

this.DataAccessObject = DataSource.DataAccessObject;

I'm not sure if that's the correct solution or not, but it got me past the initial problem. However, when trying to call remote methods, the following error occurs:

/path/to/project/node_modules/loopback-datasource-juggler/lib/dao.js:757
  this.getDataSource().connector.all(this.modelName, query, function (err, dat
                                 ^
TypeError: Object #<RemoteConnector> has no method 'all'
    at Function.find (/path/to/project/node_modules/loopback-datasource-juggler/lib/dao.js:757:34)
    at SharedMethod.invoke (/path/to/project/node_modules/loopback/node_modules/strong-remoting/lib/shared-method.js:207:17)
    at HttpContext.invoke (/path/to/project/node_modules/loopback/node_modules/strong-remoting/lib/http-context.js:243:12)
    at /path/to/project/node_modules/loopback/node_modules/strong-remoting/lib/remote-objects.js:475:9
    at execStack (/path/to/project/node_modules/loopback/node_modules/strong-remoting/lib/remote-objects.js:346:7)
    at /path/to/project/node_modules/loopback/lib/application.js:334:13
    at /path/to/project/node_modules/loopback/lib/models/model.js:267:5
    at /path/to/project/node_modules/loopback/lib/models/acl.js:443:19
    at /path/to/project/node_modules/loopback/node_modules/async/lib/async.js:254:17
    at async.each (/path/to/project/node_modules/loopback/node_modules/async/lib/async.js:121:20)

Just wanted to post that here in case it might be useful.

Eric

There is a mismatch between connector and DataAccessObject (methods mixed in from a connector). For example,

connector: all
dao: find

connector: find
dao: findById

Either the remote connector can bridge it or we should start to make them consistent. BTW, the mismatch was a legacy from jugglingdb.

I have been experiencing the same issue with incomplete DAO methods. See: #491

Any traction on this issue?

@BerkeleyTrue yep. @kraman created the loopback-connector-remote which correctly implements the relation mixin. This is working well for us in an internal project in node. In theory it should be working in browsers as well (using browserify).

^^^^

@offlinehacker @fabien @eabruzzese

Do you mean the loopback-connector-remote?

@BerkeleyTrue yes, loopback-connector-remote

Woot! Thanks @kraman @ritch . Nice work, thats solved. Now another issue has arisen!

I think I'm experiencing the same issue. I'm following this doc in an API with a container and I have an error when I add relations to my container model.

{
  "name": "Container",
  "base": "PersistedModel",
  "properties": {
    "name": {
      "type": "string"
    }
  },
  "validations": [],
  "relations": {},
  "acls": [],
  "methods": {}
}

Here's my container.json and here's the error :

TypeError: Cannot call method 'call' of undefined
    at EventEmitter.<anonymous> (/home/mowso/Documents/loopback-examples/test/node_modules/loopback-datasource-juggler/lib/datasource.js:434:37)
    at EventEmitter.g (events.js:180:16)
    at EventEmitter.emit (events.js:95:17)
    at DataSource.setupDataAccess (/home/mowso/Documents/loopback-examples/test/node_modules/loopback-datasource-juggler/lib/datasource.js:540:14)
    at DataSource.attach (/home/mowso/Documents/loopback-examples/test/node_modules/loopback-datasource-juggler/lib/datasource.js:752:8)
    at Function.ModelClass.attachTo (/home/mowso/Documents/loopback-examples/test/node_modules/loopback-datasource-juggler/lib/model-builder.js:336:16)
    at Registry.configureModel (/home/mowso/Documents/loopback-examples/test/node_modules/loopback/lib/registry.js:238:15)
    at configureModel (/home/mowso/Documents/loopback-examples/test/node_modules/loopback/lib/application.js:441:16)
    at EventEmitter.app.model (/home/mowso/Documents/loopback-examples/test/node_modules/loopback/lib/application.js:133:5)
    at /home/mowso/Documents/loopback-examples/test/node_modules/loopback-boot/lib/executor.js:190:9

Any ideas :grin: ?

I got the same issue as @Mowso here. Created an S3 container and relationships on a Model throw the same error.

The answer is that when implementing your own DataAccessObject you need to mixin into it the Original dao and apply changes to it.

e.g.

const mixin = require('loopback-datasource-juggler').ModelBaseClass.mixin;
  connector.DataAccessObject = function () {
  };
  mixin.apply(connector.DataAccessObject, [dataSource.constructor.DataAccessObject]);

I got same problem as @Mowso here. @regevbr can you give a complete example how to solve this problem.

Here's my container.json file :

  "validations": [],
  "relations": {
    "metadata": {
      "type": "hasOne",
      "model": "Media",
      "foreignKey": ""
    }
  },
  "acls": [],
  "methods": {}

And this is my media.json file :

  "validations": [],
  "relations": {
    "content": {
      "type": "belongsTo",
      "model": "Container",
      "foreignKey": "containerId"
    }
  },
  "acls": [],
  "methods": {}

Got this error

```
modelClass[relation.type].call(modelClass, relationName, params);
^

TypeError: Cannot read property 'call' of undefined
at EventEmitter. (/Users/mac/Project/project-api/node_modules/loopback-datasource-juggler/lib/datasource.js:489:37)
at Object.onceWrapper (events.js:315:30)
at emitOne (events.js:116:13)
at EventEmitter.emit (events.js:211:7)
at DataSource.setupDataAccess (/Users/mac/Project/project-api/node_modules/loopback-datasource-juggler/lib/datasource.js:652:14)
at DataSource.attach (/Users/mac/Project/project-api/node_modules/loopback-datasource-juggler/lib/datasource.js:882:8)
at Function.ModelClass.attachTo (/Users/mac/Project/project-api/node_modules/loopback-datasource-juggler/lib/model-builder.js:374:16)
at Registry.configureModel (/Users/mac/Project/project-api/node_modules/loopback/lib/registry.js:235:15)
at configureModel (/Users/mac/Project/project-api/node_modules/loopback/lib/application.js:546:16)
at Function.app.model (/Users/mac/Project/project-api/node_modules/loopback/lib/application.js:126:5)
at /Users/mac/Project/project-api/node_modules/loopback-boot/lib/executor.js:203:9
at Array.forEach ()
at setupModels (/Users/mac/Project/project-api/node_modules/loopback-boot/lib/executor.js:199:23)
at execute (/Users/mac/Project/project-api/node_modules/loopback-boot/lib/executor.js:40:3)
at bootLoopBackApp (/Users/mac/Project/project-api/node_modules/loopback-boot/index.js:154:3)
at Object. (/Users/mac/Project/project-api/server/server.js:41:1)```

I created a rewrite of the stroage component that works with relations and acl - loopback-component-flatstorage
You can check out the code there and see how I solved the issue when you create you own DataAccessObject

I have the same issue with the same stacktrace when creating two different models Contacts and Cities which are from two different soap based data sources.

Was this page helpful?
0 / 5 - 0 ratings