creating custom components and running with NoFlo - mongodb

I am creating a custom component which interfaces with MongoDB. I wrote a CoffeeScript file which just connects to MongoDB, and stored it at noflo/components folder.
MongoBase.coffee
noflo = require "noflo"
mongodb = require "mongodb"
url = require "url"
class exports.MongoBase extends noflo.Component
constructor: ->
super
#inPorts =
url: new noflo.Port()
#inPorts.url.on "data", (data) =>
try
#parseConnectionString(data)
#MongoClient = mongodb.MongoClient;
#MongoClient.connect #serverUrl, (err, db) ->
if err
console.log("Error in connecting to MongoDB")
else
console.log("Connected to MongoDB")
catch error
console.log(error)
parseConnectionString: (connectionString) =>
databaseUrl = try
url.parse(connectionString)
catch error
console.log(error)
[..., #serverUrl, #databaseName] = databaseUrl.split('/')
#serverUrl = "mongo://" + #serverUrl
I added the following entry to component.json
"MongoBase": "components/MongoBase.coffee"
In addition to this, I created a mongo.fbp file to check the flow of the component. The FBP file has the following code:
'mongodb://localhost:27017/test' -> url DocReader(MongoBase)
On running noflo mongo.fbp, I get the following error:
/home/saurabh/workspace/noflo/node_modules/fbp/lib/fbp.js:1628
edges.forEach(function (o, i) {
^
TypeError: Object #<Object> has no method 'forEach'
at Object.parser.registerEdges (/home/saurabh/workspace/noflo/node_modules/fbp/lib/fbp.js:1628:15)
at peg$c25 (/home/saurabh/workspace/noflo/node_modules/fbp/lib/fbp.js:60:50)
at peg$parseline (/home/saurabh/workspace/noflo/node_modules/fbp/lib/fbp.js:749:30)
at peg$parsestart (/home/saurabh/workspace/noflo/node_modules/fbp/lib/fbp.js:282:12)
at Object.parse (/home/saurabh/workspace/noflo/node_modules/fbp/lib/fbp.js:1650:18)
at Object.exports.loadFBP (/home/saurabh/workspace/noflo/lib/Graph.js:1065:33)
at /home/saurabh/workspace/noflo/lib/Graph.js:1116:24
at fs.js:268:14
at Object.oncomplete (fs.js:107:15)
Is there something wrong with my code, or the steps I am using to run the code?

You may have figured this out already, as it's been several month's since you asked, but I believe you need to add the getComponent() method to your class before you export it.
noflo = require "noflo"
mongodb = require "mongodb"
url = require "url"
class MongoBase extends noflo.Component
constructor: ->
super
#inPorts =
url: new noflo.Port()
#inPorts.url.on "data", (data) =>
try
#parseConnectionString(data)
#MongoClient = mongodb.MongoClient;
#MongoClient.connect #serverUrl, (err, db) ->
if err
console.log("Error in connecting to MongoDB")
else
console.log("Connected to MongoDB")
catch error
console.log(error)
parseConnectionString: (connectionString) =>
databaseUrl = try
url.parse(connectionString)
catch error
console.log(error)
[..., #serverUrl, #databaseName] = databaseUrl.split('/')
#serverUrl = "mongo://" + #serverUrl
MongoBase.getComponent = -> new MongoBase
exports.MongoBase = MongoBase
Additionally, in your graph for the component loader to work you need to specify the package your component lives in. If your package.json/component.json have a name entry like "name": "mongo-base" then you'd have to specify this in the FBP graph, like so:
'mongodb://localhost:27017/test' -> url DocReader(mongo-base/MongoBase)
N.B.: The loader clobbers any instances of 'noflo-' in the package name, so this needs to be taken into account. E.g. the name 'noflo-mongo' would get turned into just 'mongo', so when invoking the package's components you'd write in the fbp DocReader(mongo/MongoBase) and not DocReader(noflo-mongo/MongoBase).

Related

Class variable is undefined... despite being defined

I have a class called RouteBinder that looks like this:
class RouteBinder
constructor: (#server, #pool) ->
bindRoute: (name, fn, method = "post", useDb = true) ->
#server[method]("/api/accounts/v1/" + name, (req, res, next) ->
client = await #pool.connect() if useDb?
await fn req, res, next, client
await #pool.release() if useDb?
)
I declare it and call it like this:
binder = new RouteBinder server, pool
binder.bindRoute "login", controllers.login
(Pool is node-postgres's Pool and is declared and tested earlier like this)
pool = new Pool
[...]
try
client = await pool.connect()
await client.query 'SELECT 1=1'
catch e
console.fatal "Could not connect to database: #{e}"
return
finally
try client.release() if client?
catch e
console.fatal "Couldn't release client: #{e}"
return
console.info 'Database is OK!'
When running this, I get this error:
02/14 18:44:34 error (node:11855) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'connect' of undefined
at _callee2$ (/home/vi/[redacted]_accounts/main.js:136:38)
at tryCatch (/home/vi/[redacted]_accounts/node_modules/regenerator-runtime/runtime.js:45:40)
at Generator.invoke [as _invoke] (/home/vi/[redacted]_accounts/node_modules/regenerator-runtime/runtime.js:271:22)
at Generator.prototype.(anonymous function) [as next] (/home/vi/[redacted]_accounts/node_modules/regenerator-runtime/runtime.js:97:21)
at asyncGeneratorStep (/home/vi/[redacted]_accounts/node_modules/#babel/runtime/helpers/asyncToGenerator.js:3:24)
at _next (/home/vi/[redacted]_accounts/node_modules/#babel/runtime/helpers/asyncToGenerator.js:25:9)
at /home/vi/[redacted]_accounts/node_modules/#babel/runtime/helpers/asyncToGenerator.js:32:7
at new Promise (<anonymous>)
at /home/vi/[redacted]_accounts/node_modules/#babel/runtime/helpers/asyncToGenerator.js:21:12
at /home/vi/[redacted]_accounts/main.js:166:26
02/14 18:44:34 error (node:11855) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
02/14 18:44:34 error (node:11855) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
I'm using CoffeeScript compiled transpiled with Babel. My .babelrc looks like this:
{
"presets": ["#babel/env"],
"plugins": [
["#babel/plugin-transform-runtime",
{
"regenerator": true
}
]
]
}
Sorry if it's a rookie question, I'm still learning and would love all the advice I can get.
I figured out my mistake. Both #pool and #server were defined, however, the inline function (handler) for #server[method] was running in the context of that function.
The solution was to bind it to the RouteBinder instance using .bind(#) (or .bind(this), if you prefer)
bindRoute: (name, fn, method = "post", useDb = true) ->
#server[method]("/api/accounts/v1/" + name, ((req, res, next) ->
console.log "pool", #pool
client = await #pool.connect() if useDb?
await fn req, res, next, client
await #pool.release() if useDb?
).bind(#))

Error # Database Connection Initialization : Error: database name must be a string

i just try to connect mongodb. but it show
Error # Database Connection Initialization : Error: database name
must be a string
Following is code:
try {
mongoDb.connect("localhost:27017/sample");
var db = mongoDb
}
catch (err) {
console.log('Error # Database Connection Initialization : ' + err);
}
Please try this
// Initialize connection once
MongoClient.connect("mongodb://localhost:27017/sample", function(err, database) {
if(err) return console.error(err);
db = database;
// the Mongo driver recommends starting the server here because most apps *should* fail to start if they have no DB. If yours is the exception, move the server startup elsewhere.
});

Typescript not inserting into Mongo Collection

I am using Ionic2 with Meteor/MongoDb.
I have a collection, that I am trying to insert a message object into. However, the code seems to freeze where it tries to do the insert. However, if I try insert the message object from a different place (i.e. invoke setLocalMessage(message: Message)), it does so successfully. This makes me think, the problem is not with the collection or message objects, but rather the way I am calling the function that does the insert.
private localMessageCollection: Mongo.Collection<Message> = new Mongo.Collection<Message>(null);
and
private loadMessages(): void {
let promise: Promise<string> = this.utilityService.getLoggedInPerson();
if (promise) {
promise.then((data) => {
this.personModelLoggedIn = JSON.parse(data);
if (this.personModelLoggedIn) {
this.senderId = 'P' + this.personModelLoggedIn.id;
this.title = this.activeChat.title;
this.picture = this.activeChat.picture;
this.subscribe('messages', this.activeChat._id, this.senderId, () => {
this.autorun(() => {
let promiseLocalMessages: Promise<Mongo.Collection<Message>> = this.findLocalMessages();
promiseLocalMessages.then((messageData: Mongo.Collection<Message>) => {
messageData.find().forEach((message: Message) => {
this.setLocalMessage(message);
});
});
let promiseMessages: Promise<Mongo.Collection<Message>> = this.findMessages();
promiseMessages.then((messageData: Mongo.Collection<Message>) => {
messageData.find().forEach((message: Message) => {
this.setLocalMessage(message);
});
});
});
});
} else {
this.nav.push(LoginPage, {
fromMessages: true
});
}
});
} else {
this.nav.push(LoginPage, {
fromMessages: true
});
}
}
and
private setLocalMessage(message: Message): void {
console.log('setLocalNessage: ' + message._id);
console.log(this.localMessageCollection);
this.localMessageCollection.insert(message);
console.log('setLocalNessage done: ' + message);
}
output
setLocalNessage: eC7hDZ4Z6ZwTnjP4h
Mongo.Collection {_makeNewID: function, _transform: null, _connection: null, _collection: LocalCollection, _name: null…}
but then it freezes.
If anyone can assist I would appreciate it.
UPDATE
It is freezing in the Meteor api on this line:
}Meteor.default_connection=Meteor.connection;Meteor.connect=DDP.connect}).call(this);if(typeof Package==="undefined")Package={};(function(pkg,symbols){for(var s in symbols)s in pkg||(pkg[s]=symbols[s])})(Package["ddp-client"]={},{DDP:DDP,LivedataTest:LivedataTest})})();(function(){var Meteor=Package.meteor.Meteor;var global=Package.meteor.global;var meteorEnv=Package.meteor.meteorEnv;var DDP=Package["ddp-client"].DDP;if(typeof Package==="undefined")Package={};(function(pkg,symbols){for(var s in symbols)s in pkg||(pkg[s]=symbols[s])})(Package.ddp={},{DDP:DDP})})();(function(){var Meteor=Package.meteor.Meteor;var global=Package.meteor.global;var meteorEnv=Package.meteor.meteorEnv;var _=Package.underscore._;var LocalCollection=Package.minimongo.LocalCollection;var Minimongo=Package.minimongo.Minimongo;var check=Package.check.check;var Match=Package.check.Match;var EJSON=Package.ejson.EJSON;var DDP=Package["ddp-client"].DDP;var meteorInstall=Package.modules.meteorInstall;var Buffer=Package.modules.Buffer;var process=Package.modules.process;var Symbol=Package["ecmascript-runtime"].Symbol;var Map=Package["ecmascript-runtime"].Map;var Set=Package["ecmascript-runtime"].Set;var meteorBabelHelpers=Package["babel-runtime"].meteorBabelHelpers;var Promise=Package.promise.Promise;var AllowDeny;var require=meteorInstall({node_modules:{meteor:{"allow-deny":{"allow-deny.js":function(){AllowDeny={CollectionPrototype:{}};var CollectionPrototype=AllowDeny.CollectionPrototype;CollectionPrototype.allow=function(options){addValidator(this,"allow",options)};CollectionPrototype.deny=function(options){addValidator(this,"deny",options)};CollectionPrototype._defineMutationMethods=function(options){var self=this;options=options||{};self._restricted=false;self._insecure=undefined;self._validators={insert:{allow:[],deny:[]},update:{allow:[],deny:[]},remove:{allow:[],deny:[]},upsert:{allow:[],deny:[]},fetch:[],fetchAllFields:false};if(!self._name)return;self._prefix="/"+self._name+"/";if(self._connection&&(self._connection===Meteor.server||Meteor.isClient)){(function(){var m={};_.each(["insert","update","remove"],function(method){var methodName=self._prefix+method;if(options.useExisting){var handlerPropName=Meteor.isClient?"_methodHandlers":"method_handlers";if(self._connection[handlerPropName]&&typeof self._connection[handlerPropName][methodName]==="function")return}m[methodName]=function(){check(arguments,[Match.Any]);var args=_.toArray(arguments);try{var generatedId=null;if(method==="insert"&&!_.has(args[0],"_id")){generatedId=self._makeNewID()}if(this.isSimulation){if(generatedId!==null)args[0]._id=generatedId;return self._collection[method].apply(self._collection,args)}if(method!=="insert")throwIfSelectorIsNotId(args[0],method);if(self._restricted){if(self._validators[method].allow.length===0){throw new Meteor.Error(403,"Access denied. No allow validators set on restricted "+"collection for method '"+method+"'.")}var validatedMethodName="_validated"+method.charAt(0).toUpperCase()+method.slice(1);args.unshift(this.userId);method==="insert"&&args.push(generatedId);return self[validatedMethodName].apply(self,args)}else if(self._isInsecure()){if(generatedId!==null)args[0]._id=generatedId;return self._collection[method].apply(self._collection,args)}else{throw new Meteor.Error(403,"Access denied")}}catch(e){if(e.name==="MongoError"||e.name==="MinimongoError"){throw new Meteor.Error(409,e.toString())}else{throw e}}}});self._connection.methods(m)})()}};CollectionPrototype._updateFetch=function(fields){var self=this;if(!self._validators.fetchAllFields){if(fields){self._validators.fetch=_.union(self._validators.fetch,fields)}else{self._validators.fetchAllFields=true;self._validators.fetch=null}}};CollectionPrototype._isInsecure=function(){var self=this;if(self._insecure===undefined)return!!Package.insecure;return self._insecure};CollectionPrototype._validatedInsert=function(userId,doc,generatedId){var self=this;if(_.any(self._validators.insert.deny,function(validator){return validator(userId,docToValidate(validator,doc,generatedId))})){throw new Meteor.Error(403,"Access denied")}if(_.all(self._validators.insert.allow,function(validator){return!validator(userId,docToValidate(validator,doc,generatedId))})){throw new Meteor.Error(403,"Access denied")}if(generatedId!==null)doc._id=generatedId;self._collection.insert.call(self._collection,doc)};CollectionPrototype._validatedUpdate=function(userId,selector,mutator,options){var self=this;check(mutator,Object);options=_.clone(options)||{};if(!LocalCollection._selectorIsIdPerhapsAsObject(selector))throw new Error("validated update should be of a single ID");if(options.upsert)throw new Meteor.Error(403,"Access denied. Upserts not "+"allowed in a restricted collection.");var noReplaceError="Access denied. In a restricted collection you can only"+" update documents, not replace them. Use a Mongo update operator, such "+"as '$set'.";var fields=[];if(_.isEmpty(mutator)){throw new Meteor.Error(403,noReplaceError)}_.each(mutator,function(params,op){if(op.charAt(0)!=="$"){throw new Meteor.Error(403,noReplaceError)}else if(!_.has(ALLOWED_UPDATE_OPERATIONS,op)){throw new Meteor.Error(403,"Access denied. Operator "+op+" not allowed in a restricted collection.")}else{_.each(_.keys(params),function(field){if(field.indexOf(".")!==-1)field=field.substring(0,field.indexOf("."));if(!_.contains(fields,field))fields.push(field)})}});var findOptions={transform:null};if(!self._validators.fetchAllFields){findOptions.fields={};_.each(self._validators.fetch,function(fieldName){findOptions.fields[fieldName]=1})}var doc=self._collection.findOne(selector,findOptions);if(!doc)return 0;if(_.any(self._validators.update.deny,function(validator){var factoriedDoc=transformDoc(validator,doc);return validator(userId,factoriedDoc,fields,mutator)})){throw new Meteor.Error(403,"Access denied")}if(_.all(self._validators.update.allow,function(validator){var factoriedDoc=transformDoc(validator,doc);return!validator(userId,factoriedDoc,fields,mutator)})){throw new Meteor.Error(403,"Access denied")}options._forbidReplace=true;return self._collection.update.call(self._collection,selector,mutator,options)};var ALLOWED_UPDATE_OPERATIONS={$inc:1,$set:1,$unset:1,$addToSet:1,$pop:1,$pullAll:1,$pull:1,$pushAll:1,$push:1,$bit:1};CollectionPrototype._validatedRemove=function(userId,selector){var self=this;var findOptions={transform:null};if(!self._validators.fetchAllFields){findOptions.fields={};_.each(self._validators.fetch,function(fieldName){findOptions.fields[fieldName]=1})}var doc=self._collection.findOne(selector,findOptions);if(!doc)return 0;if(_.any(self._validators.remove.deny,function(validator){return validator(userId,transformDoc(validator,doc))})){throw new Meteor.Error(403,"Access denied")}if(_.all(self._validators.remove.allow,function(validator){return!validator(userId,transformDoc(validator,doc))})){throw new Meteor.Error(403,"Access denied")}return self._collection.remove.call(self._collection,selector)};CollectionPrototype._callMutatorMethod=function(){function _callMutatorMethod(name,args,callback){if(Meteor.isClient&&!callback&&!alreadyInSimulation()){callback=function(){function callback(err){if(err)Meteor._debug(name+" failed: "+(err.reason||err.stack))}return callback}()}var firstArgIsSelector=name==="update"||name==="remove";if(firstArgIsSelector&&!alreadyInSimulation()){throwIfSelectorIsNotId(args[0],name)}var mutatorMethodName=this._prefix+name;return this._connection.apply(mutatorMethodName,args,{returnStubValue:true},callback)}return _callMutatorMethod}();function transformDoc(validator,doc){if(validator.transform)return validator.transform(doc);return doc}function docToValidate(validator,doc,generatedId){var ret=doc;if(validator.transform){ret=EJSON.clone(doc);if(generatedId!==null){ret._id=generatedId}ret=validator.transform(ret)}return ret}function addValidator(collection,allowOrDeny,options){var VALID_KEYS=["insert","update","remove","fetch","transform"];_.each(_.keys(options),function(key){if(!_.contains(VALID_KEYS,key))throw new Error(allowOrDeny+": Invalid key: "+key)});collection._restricted=true;_.each(["insert","update","remove"],function(name){if(options.hasOwnProperty(name)){if(!(options[name]instanceof Function)){throw new Error(allowOrDeny+": Value for `"+name+"` must be a function")}if(options.transform===undefined){options[name].transform=collection._transform}else{options[name].transform=LocalCollection.wrapTransform(options.transform)}collection._validators[name][allowOrDeny].push(options[name])}});if(options.update||options.remove||options.fetch){if(options.fetch&&!(options.fetch instanceof Array)){throw new Error(allowOrDeny+": Value for `fetch` must be an array")}collection._updateFetch(options.fetch)}}function throwIfSelectorIsNotId(selector,methodName){if(!LocalCollection._selectorIsIdPerhapsAsObject(selector)){throw new Meteor.Error(403,"Not permitted. Untrusted code may only "+methodName+" documents by ID.")}}function alreadyInSimulation(){var enclosing=DDP._CurrentInvocation.get();return enclosing&&enclosing.isSimulation}}}}}},{extensions:[".js",".json"]});require("./node_modules/meteor/allow-deny/allow-deny.js");if(typeof Package==="undefined")Package={};(function(pkg,symbols){for(var s in symbols)s in pkg||(pkg[s]=symbols[s])})(Package["allow-deny"]={},{AllowDeny:AllowDeny})})();(function(){var Meteor=Package.meteor.Meteor;var global=Package.meteor.global;var meteorEnv=Package.meteor.meteorEnv;var AllowDeny=Package["allow-deny"].AllowDeny;var Random=Package.random.Random;var EJSON=Package.ejson.EJSON;var _=Package.underscore._;var LocalCollection=Package.minimongo.LocalCollection;var Minimongo=Package.minimongo.Minimongo;var DDP=Package["ddp-client"].DDP;var Tracker=Package.tracker.Tracker;var Deps=Package.tracker.Deps;var DiffSequence=Package["diff-sequence"].DiffSequence;var MongoID=Package["mongo-id"].MongoID;var check=Package.check.check;var Match=Package.check.Match;var meteorInstall=Package.modules.meteorInstall;var Buffer=Package.modules.Buffer;var process=Package.modules.process;var Symbol=Package["ecmascript-runtime"].Symbol;var Map=Package["ecmascript-runtime"].Map;var Set=Package["ecmascript-runtime"].Set;var meteorBabelHelpers=Package["babel-runtime"].meteorBabelHelpers;var Promise=Package.promise.Promise;var LocalCollectionDriver,Mongo;var require=meteorInstall({node_modules:{meteor:{mongo:{"local_collection_driver.js":function(){LocalCollectionDriver=function LocalCollectionDriver(){var self=this;self.noConnCollections={}};var ensureCollection=function ensureCollection(name,collections){if(!(name in collections))collections[name]=new LocalCollection(name);return collections[name]};_.extend(LocalCollectionDriver.prototype,{open:function(){function open(name,conn){var self=this;if(!name)return new LocalCollection;if(!conn){return ensureCollection(name,self.noConnCollections)}if(!conn._mongo_livedata_collections)conn._mongo_livedata_collections={};return ensureCollection(name,conn._mongo_livedata_collections)}return open}()});LocalCollectionDriver=new LocalCollectionDriver},"collection.js":function(require,exports,module){Mongo={};Mongo.Collection=function(name,options){var self=this;if(!(self instanceof Mongo.Collection))throw new Error('use "new" to construct a Mongo.Collection');if(!name&&name!==null){Meteor._debug("Warning: creating anonymous collection. It will not be "+"saved or synchronized over the network. (Pass null for "+"the collection name to turn off this warning.)");name=null}if(name!==null&&typeof name!=="string"){throw new Error("First argument to new Mongo.Collection must be a string or null")}if(options&&options.methods){options={connection:options}}if(options&&options.manager&&!options.connection){options.connection=options.manager}options=_.extend({connection:undefined,idGeneration:"STRING",transform:null,_driver:undefined,_preventAutopublish:false},options);switch(options.idGeneration){case"MONGO":self._makeNewID=function(){var src=name?DDP.randomStream("/collection/"+name):Random.insecure;return new Mongo.ObjectID(src.hexString(24))};break;case"STRING":default:self._makeNewID=function(){var src=name?DDP.randomStream("/collection/"+name):Random.insecure;return src.id()};break}self._transform=LocalCollection.wrapTransform(options.transform);if(!name||options.connection===null)self._connection=null;else if(options.connection)self._connection=options.connection;else if(Meteor.isClient)self._connection=Meteor.connection;else self._connection=Meteor.server;if(!options._driver){if(name&&self._connection===Meteor.server&&typeof MongoInternals!=="undefined"&&MongoInternals.defaultRemoteCollectionDriver){options._driver=MongoInternals.defaultRemoteCollectionDriver()}else{options._driver=LocalCollectionDriver}}self._collection=options._driver.open(name,self._connection);self._name=name;self._driver=options._driver;if(self._connection&&self._connection.registerStore){var ok=self._connection.registerStore(name,{beginUpdate:function(){function beginUpdate(batchSize,reset){if(batchSize>1||reset)self._collection.pauseObservers();if(reset)self._collection.remove({})}return beginUpdate}(),update:function(){function update(msg){var mongoId=MongoID.idParse(msg.id);var doc=self._collection.findOne(mongoId);if(msg.msg==="replace"){var replace=msg.replace;if(!replace){if(doc)self._collection.remove(mongoId)}else if(!doc){self._collection.insert(replace)}else{self._collection.update(mongoId,replace)}return}else if(msg.msg==="added"){if(doc){throw new Error("Expected not to find a document already present for an add")}self._collection.insert(_.extend({_id:mongoId},msg.fields))}else if(msg.msg==="removed"){if(!doc)throw new Error("Expected to find a document already present for removed");self._collection.remove(mongoId)}else if(msg.msg==="changed"){if(!doc)throw new Error("Expected to find a document to change");if(!_.isEmpty(msg.fields)){var modifier={};_.each(msg.fields,function(value,key){if(value===undefined){if(!modifier.$unset)modifier.$unset={};modifier.$unset[key]=1}else{if(!modifier.$set)modifier.$set={};modifier.$set[key]=value}});self._collection.update(mongoId,modifier)}}else{throw new Error("I don't know how to deal with this message")}}return update}(),endUpdate:function(){function endUpdate(){self._collection.resumeObservers()}return endUpdate}(),saveOriginals:function(){function saveOriginals(){self._collection.saveOriginals()}return saveOriginals}(),retrieveOriginals:function(){function retrieveOriginals(){return self._collection.retrieveOriginals()}return retrieveOriginals}(),getDoc:function(){function getDoc(id){return self.findOne(id)}return getDoc}(),_getCollection:function(){function _getCollection(){return self}return _getCollection}()});if(!ok){var message='There is already a collection named "'+name+'"';if(options._suppressSameNameError===true){console.warn?console.warn(message):console.log(message)}else{throw new Error(message)}}}if(options.defineMutationMethods!==false){try{self._defineMutationMethods({useExisting:options._suppressSameNameError===true})}catch(error){if(error.message==="A method named '/"+name+"/insert' is already defined")throw new Error('There is already a collection named "'+name+'"');throw error}}if(Package.autopublish&&!options._preventAutopublish&&self._connection&&self._connection.publish){self._connection.publish(null,function(){return self.find()},{is_auto:true})}};_.extend(Mongo.Collection.prototype,{_getFindSelector:function(){function _getFindSelector(args){if(args.length==0)return{};else return args[0]}return _getFindSelector}(),_getFindOptions:function(){function _getFindOptions(args){var self=this;if(args.length<2){return{transform:self._transform}}else{check(args[1],Match.Optional(Match.ObjectIncluding({fields:Match.Optional(Match.OneOf(Object,undefined)),sort:Match.Optional(Match.OneOf(Object,Array,Function,undefined)),limit:Match.Optional(Match.OneOf(Number,undefined)),skip:Match.Optional(Match.OneOf(Number,undefined))})));return _.extend({transform:self._transform},args[1])}}return _getFindOptions}(),find:function(){function find(){var self=this;var argArray=_.toArray(arguments);return self._collection.find(self._getFindSelector(argArray),self._getFindOptions(argArray))}return find}(),findOne:function(){function findOne(){var self=this;var argArray=_.toArray(arguments);return self._collection.findOne(self._getFindSelector(argArray),self._getFindOptions(argArray))}return findOne}()});Mongo.Collection._publishCursor=function(cursor,sub,collection){var observeHandle=cursor.observeChanges({added:function(){function added(id,fields){sub.added(collection,id,fields)}return added}(),changed:function(){function changed(id,fields){sub.changed(collection,id,fields)}return changed}(),removed:function(){function removed(id){sub.removed(collection,id)}return removed}()});sub.onStop(function(){observeHandle.stop()});return observeHandle};Mongo.Collection._rewriteSelector=function(selector){if(LocalCollection._selectorIsId(selector))selector={_id:selector};if(_.isArray(selector)){throw new Error("Mongo selector can't be an array.")}if(!selector||"_id"in selector&&!selector._id)return{_id:Random.id()};var ret={};_.each(selector,function(value,key){if(value instanceof RegExp){ret[key]=convertRegexpToMongoSelector(value)}else if(value&&value.$regex instanceof RegExp){ret[key]=convertRegexpToMongoSelector(value.$regex);if(value.$options!==undefined)ret[key].$options=value.$options}else if(_.contains(["$or","$and","$nor"],key)){ret[key]=_.map(value,function(v){return Mongo.Collection._rewriteSelector(v)})}else{ret[key]=value}});return ret};function convertRegexpToMongoSelector(regexp){check(regexp,RegExp);var selector={$regex:regexp.source};var regexOptions="";if(regexp.ignoreCase)regexOptions+="i";if(regexp.multiline)regexOptions+="m";if(regexOptions)selector.$options=regexOptions;return selector}Mongo.Collection.prototype.insert=function(){function insert(doc,callback){if(!doc){throw new Error("insert requires an argument")}doc=_.extend({},doc);if("_id"in doc){if(!doc._id||!(typeof doc._id==="string"||doc._id instanceof Mongo.ObjectID)){throw new Error("Meteor requires document _id fields to be non-empty strings or ObjectIDs")}}else{var generateId=true;if(this._isRemoteCollection()){var enclosing=DDP._CurrentInvocation.get();if(!enclosing){generateId=false}}if(generateId){doc._id=this._makeNewID()}}var chooseReturnValueFromCollectionResult=function(){function chooseReturnValueFromCollectionResult(result){if(doc._id){return doc._id}doc._id=result;return result}return chooseReturnValueFromCollectionResult}();var wrappedCallback=wrapCallback(callback,chooseReturnValueFromCollectionResult);if(this._isRemoteCollection()){var result=this._callMutatorMethod("insert",[doc],wrappedCallback);return chooseReturnValueFromCollectionResult(result)}try{var _result=this._collection.insert(doc,wrappedCallback);return chooseReturnValueFromCollectionResult(_result)}catch(e){if(callback){callback(e);return null}throw e}}return insert}();Mongo.Collection.prototype.update=function(){function update(selector,modifier){for(var _len=arguments.length,optionsAndCallback=Array(_len>2?_len-2:0),_key=2;_key<_len;_key++){optionsAndCallback[_key-2]=arguments[_key]}var callback=popCallbackFromArgs(optionsAndCallback);selector=Mongo.Collection._rewriteSelector(selector);var options=_.clone(optionsAndCallback[0])||{};if(options&&options.upsert){if(options.insertedId){if(!(typeof options.insertedId==="string"||options.insertedId instanceof Mongo.ObjectID))throw new Error("insertedId must be string or ObjectID")}else if(!selector._id){options.insertedId=this._makeNewID()}}var wrappedCallback=wrapCallback(callback);if(this._isRemoteCollection()){var args=[selector,modifier,options];return this._callMutatorMethod("update",args,wrappedCallback)}try{return this._collection.update(selector,modifier,options,wrappedCallback)}catch(e){if(callback){callback(e);return null}throw e}}return update}();Mongo.Collection.prototype.remove=function(){function remove(selector,callback){selector=Mongo.Collection._rewriteSelector(selector);var wrappedCallback=wrapCallback(callback);if(this._isRemoteCollection()){return this._callMutatorMethod("remove",[selector],wrappedCallback)}try{return this._collection.remove(selector,wrappedCallback)}catch(e){if(callback){callback(e);return null}throw e}}return remove}();Mongo.Collection.prototype._isRemoteCollection=function(){function _isRemoteCollection(){return this._connection&&this._connection!==Meteor.server}return _isRemoteCollection}();function wrapCallback(callback,convertResult){if(!callback){return}convertResult=convertResult||_.identity;return function(error,result){callback(error,!error&&convertResult(result))}}Mongo.Collection.prototype.upsert=function(){function upsert(selector,modifier,options,callback){if(!callback&&typeof options==="function"){callback=options;options={}}var updateOptions=_.extend({},options,{_returnObject:true,upsert:true});return this.update(selector,modifier,updateOptions,callback)}return upsert}();Mongo.Collection.prototype._ensureIndex=function(index,options){var self=this;if(!self._collection._ensureIndex)throw new Error("Can only call _ensureIndex on server collections");self._collection._ensureIndex(index,options)};Mongo.Collection.prototype._dropIndex=function(index){var self=this;if(!self._collection._dropIndex)throw new Error("Can only call _dropIndex on server collections");self._collection._dropIndex(index)};Mongo.Collection.prototype._dropCollection=function(){var self=this;if(!self._collection.dropCollection)throw new Error("Can only call _dropCollection on server collections");self._collection.dropCollection()};Mongo.Collection.prototype._createCappedCollection=function(byteSize,maxDocuments){var self=this;if(!self._collection._createCappedCollection)throw new Error("Can only call _createCappedCollection on server collections");self._collection._createCappedCollection(byteSize,maxDocuments)};Mongo.Collection.prototype.rawCollection=function(){var self=this;if(!self._collection.rawCollection){throw new Error("Can only call rawCollection on server collections")}return self._collection.rawCollection()};Mongo.Collection.prototype.rawDatabase=function(){var self=this;if(!(self._driver.mongo&&self._driver.mongo.db)){throw new Error("Can only call rawDatabase on server collections")}return self._driver.mongo.db};Mongo.ObjectID=MongoID.ObjectID;Mongo.Cursor=LocalCollection.Cursor;Mongo.Collection.Cursor=Mongo.Cursor;Mongo.Collection.ObjectID=Mongo.ObjectID;Meteor.Collection=Mongo.Collection;_.extend(Meteor.Collection.prototype,AllowDeny.CollectionPrototype);function popCallbackFromArgs(args){if(args.length&&(args[args.length-1]===undefined||args[args.length-1]instanceof Function)){return args.pop()}}}}}}},{extensions:[".js",".json"]});require("./node_modules/meteor/mongo/local_collection_driver.js");require("./node_modules/meteor/mongo/collection.js");if(typeof Package==="undefined")Package={};(function(pkg,symbols){for(var s in symbols)s in pkg||(pkg[s]=symbols[s])})(Package.mongo={},{Mongo:Mongo})})();Meteor=Package.meteor.Meteor;global=Package.meteor.global;meteorEnv=Package.meteor.meteorEnv;_=Package.underscore._;DDP=Package["ddp-client"].DDP;Mongo=Package.mongo.Mongo;Tracker=Package.tracker.Tracker;Deps=Package.tracker.Deps;

Adding a websocket "put" request in the bootstrap.js file in sails : cannot find io

I need to call a socket request from the bootstrap.js file in sails.
The bootstrap.js file has some code checking if some game engine has updated some file. If so, it needs send a message with some updated data via socket to some defined route called "/update"... e.g.
io.socket.put('/update', {history:{sessions:[1,2,3,4]}},function gotResponse(body, response) {
console.log('Server sending request ot server ');
})
The problem is that it tells me that io is not recognised.
I tried to do npm install for both sails.io.js and socket.io-client and then write:
var io = require('sails.io.js')( require('socket.io-client') );
at the top.
Unfortunately, it gives me the following error message:
C:\Users\Evolver\Documents\programming\pipegame\game6\node_modules\socket.io-client\lib\url.js:29
if (null == uri) uri = loc.protocol + '//' + loc.host;
^
TypeError: Cannot read property 'protocol' of undefined
at url (C:\Users\Evolver\Documents\programming\pipegame\game6\node_modules\socket.io-client\lib\url.js:29:29)
at lookup (C:\Users\Evolver\Documents\programming\pipegame\game6\node_modules\socket.io-client\lib\index.js:44:16)
at goAheadAndActuallyConnect (C:\Users\Evolver\Documents\programming\pipegame\game6\node_modules\sails.io.js\sails.io.js:835:21)
at selfInvoking (C:\Users\Evolver\Documents\programming\pipegame\game6\node_modules\sails.io.js\sails.io.js:812:18)
at SailsSocket.SailsIOClient.SailsSocket._connect (C:\Users\Evolver\Documents\programming\pipegame\game6\node_modules\sails.io.js\sails.io.js:831:9)
at null._onTimeout (C:\Users\Evolver\Documents\programming\pipegame\game6\node_modules\sails.io.js\sails.io.js:1463:17)
at Timer.listOnTimeout (timers.js:92:15)
Any idea ?
Ok.
It now works, once npm install has been done for socket.io-client and sails.io.js if I do exactly the following:
var socketIOClient = require('socket.io-client');
var sailsIOClient = require('sails.io.js');
// Instantiate the socket client (`io`)
var io = sailsIOClient(socketIOClient);
io.sails.url = 'http://localhost:1337';
// then I send something via my socket
io.socket.put('/update', {history:{sessions:[1,2,3,4]}},function gotResponse(body, response) {
console.log('Server sending request ot server ');
})

Grails injected Mail Service bean is null inside a controller

I am trying to use the following Grails Mail plugin: https://grails.org/plugin/mail
I've added the depedency in BuildConfig.groovy:
plugins {
//mail plugin
compile "org.grails.plugins:mail:1.0.7"
}
The I've configured it to use a specific email by adding the following code in Config.groovy:
grails {
mail {
host = "smtp.gmail.com"
port = 465
username = "-my email-"
password = "-my password-"
props = ["mail.smtp.auth":"true",
"mail.smtp.socketFactory.port":"465",
"mail.smtp.socketFactory.class":"javax.net.ssl.SSLSocketFactory",
"mail.smtp.socketFactory.fallback":"false"]
from = "no-reply#kunega.com"
}
}
I have a controller where I declare the mailService so it should be injectd as a bean:
#Secured("permitAll")
class RegisterController {
def mailService
def springSecurityService
#Transactional
def registerAccount(UserCommand userCommand) {
def model
if (springSecurityService.isLoggedIn()) {
model = [success: false, message: 'Log out to register a new account.']
response.status = 400
} else if (userCommand.validate()) {
User u = userCommand.createUser()
u.save(flush: true);
Role role = Role.findByAuthority("ROLE_USER")
UserRole.create u, role, true
def link = createLink(controller: 'register', action: 'activateAccount', params: [code: u.confirmCode])
mailService.sendMail {
async true
to 'kunega#mailinator.com'
html "Activate your account on Kunega"
}
model = [success: true, message: 'An activation link has been sent to your email.']
response.status = 201
} else {
model = [success: false, errors: userCommand.getErrors()]
response.status = 400
}
render model as JSON
}
}
I am trying to use the sendMail method it in the registerAccount method of the controller. However I get an error, which basically says that the mailService object is null. Here is the error message:
errors.GrailsExceptionResolver NullPointerException occurred when processing request: [POST] /Kunega/register/createAccount
Cannot invoke method $() on null object. Stacktrace follows:
java.lang.NullPointerException: Cannot invoke method $() on null object
at com.kunega.RegisterController$_$tt__registerAccount_closure2.doCall(RegisterController.groovy:32)
at grails.plugin.mail.MailService.sendMail(MailService.groovy:53)
at grails.plugin.mail.MailService.sendMail(MailService.groovy:59)
at com.kunega.RegisterController.$tt__registerAccount(RegisterController.groovy:29)
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:198)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.java:53)
at grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter.doFilter(RequestHolderAuthenticationFilter.java:49)
at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:82)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
And there is another strange thing that I should mention. I'm using IntelliJ Ultimate Edition, and here is a curios thing:
If you notice inside the highlighted area with red, the IDE is showing that it can't recognize the arguments inside the closure that is passed to sendEmail.
I've never used this plugin before, so I just followed the steps in the docs, but apparently something is wrong. Thank you for your help.
In your code you have:
html "Activate your account on Kunega"
which I suppose should be either:
html "Activate your account on Kunega"
or
html "Activate your account on Kunega"
otherwise you call a method html with params "Activate your account on Kunega".