'Trying to open unclosed connection' error' using Mongoose and embedded documents - connection

I'm getting a connection related error when defining a static query that filters an embedded document field.
I've tried to separate the embedded document in a separate schema file but didn't resolve the issue. Any ideas?
Error follows:
C:\development_GIT\myproject\app\models\mymodel.js:40
this.find({ text.lang_code: langCode }).sort('text.name').exec(callback);
^
Error: Trying to open unclosed connection.
at NativeConnection.Connection.open (C:\development_GIT\myproject\node_
modules\mongoose\lib\connection.js:205:15)
at Mongoose.connect (C:\development_GIT\myproject\node_modules\mongoose
\lib\index.js:156:15)
at Object.<anonymous> (C:\development_GIT\myproject\server.js:13:10)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at repl:1:1
The error is launched when using the filter { text.lang_code: langCode }
option in the following model. If I don't use the embedded document and try to filter for exampe { _id: langCode } it does not throw errors.
//MyModel.js located at ./app/models
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var MyModelSchema = new Schema({
name: { type: String, trim: true },
text: [{ name: String, lang_code: String }]
});
MyModelSchema .static({
findByLangCode : function(langCode, callback) {
this.find({ text.lang_code: langCode }).sort('text.name').exec(callback);
}
});
mongoose.model('MyModel', CategorySchema);
The first lines of my main file server.js are:
//server.js
var express = require('express');
var env = process.env.NODE_ENV || 'development';
var config = require('./config/config')[env];
var mongoose = require('mongoose');
var fs = require('fs');
require('express-namespace');
mongoose.connect(config.db);
// Bootstrap models
fs.readdirSync(__dirname + '/app/models').forEach(function (file) {
if (~file.indexOf('.js')) require(__dirname + '/app/models/' + file)
});

Solution was building the query in a different way. It seems that subdocuments can not be used inside find().
Before: (not working)
this.find({ text.lang_code: langCode }).sort('text.name').exec(callback);
After (working)
this.find().where('text.lang_code').equals(langCode).sort('text.name').exec(callback);

Im using this all the time and it works fine for me.
this.find({ 'text.lang_code': langCode }).sort('text.name').exec(callback);
MongoDb can only handle one lvl of objects, but if you give it a string like you are doing in the .where function, mongodb will do magic and match it to subdocuments :)

Related

How can I use Faker library on Artillery's Docker Image?

So my dilemma is I want to run my script, which has a processor function that uses Faker library, on Gitlab Pipeline. The problem is the Artillery does not have the Faker library. I tried installing Faker inside the docker container as an experiment, but my script is still not working.
Here's the code of my processor.js file
const Faker = require("faker");
function generateLinkData(requestParams, ctx, ee, next) {
let firstname = Faker.name.firstName();
let lastname = Faker.name.lastName();
ctx.vars["amount"] = Faker.finance.amount(5, 1000000, 2);
ctx.vars["reference"] = Faker.commerce.price(100000, 200000, 0);
ctx.vars["description"] = Faker.commerce.productDescription();
ctx.vars["email_link"] = Faker.internet.email(firstname, lastname,'mailinator.com');
ctx.vars["contact_first_name"] = firstname;
ctx.vars["contact_last_name"] = lastname;
return next();
}
module.exports = {
generateLinkData,
};
And here's the error:
node:internal/modules/cjs/loader:933
const err = new Error(message);
^
Error: Cannot find module 'faker'
Require stack:
- /builds/trial304/artillery-load-test/tests/performance/processor.js
- /home/node/artillery/core/lib/runner.js
- /home/node/artillery/lib/util.js
- /home/node/artillery/lib/console-reporter.js
- /home/node/artillery/lib/artillery-global.js
- /home/node/artillery/bin/run
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
at Function.Module._load (node:internal/modules/cjs/loader:778:27)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (/builds/trial304/artillery-load-test/tests/performance/processor.js:2:15)
at Module._compile (node:internal/modules/cjs/loader:1105:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'/builds/trial304/artillery-load-test/tests/performance/processor.js',
'/home/node/artillery/core/lib/runner.js',
'/home/node/artillery/lib/util.js',
'/home/node/artillery/lib/console-reporter.js',
'/home/node/artillery/lib/artillery-global.js',
'/home/node/artillery/bin/run'
]
}
This is the command I run inside the docker container to install faker:
npm install #faker-js/faker --save-dev
The processor won't run and causes error since it needs the Faker library and it seems the Faker library is not being recognized (??). I hope anyone could help me with this. Thank you!

Gulp wiredep error on jquery-ui

I use wiredep to get all vendor components and put them in a temporary folder, but when I add jquery-ui, wiredep fails.
gulpfile.js
gulp.task('build:vendor', ['cleanVendor'], function () {
var files = require('wiredep')();
var stream = gulp.src(files.js);
// ...other code here
});
the error output:
C:\Dev\node_modules\wiredep\wiredep.js:30
('on-error', opts.onError || function(err) { throw new Error(err); })
^
Error: Error: jquery-ui is not installed. Try running `bower install` or remove
the component from your bower.json file.
at C:\Dev\node_modules\wiredep\wiredep.js:30:56
at C:\Dev\node_modules\wiredep\lib\detect-dependencis.js:149:29
at forOwn (C:\Dev\node_modules\wiredep\node_modules\lodash\dist\lodash.js:2106:15)
at Function.forEach (C:\Dev\node_modules\wiredep\node_modules\lodash\dist\lodash.js:3303:9)
at detectDependencies (C:\Dev\node_modules\wiredep\lib\detect-dependencies.js:34:7)
at wiredep (C:\Dev\node_modules\wiredep\wiredep.js:70:39)
at Object.<anonymous> (C:\Dev\gulp\prep.js:16:33)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
bower.json:
{
"name": "project",
"version": "0.0.1",
"dependencies": {
"angular-messages": "^1.4.2",
"angular-aria": "^1.4.2",
"jquery": "^1.11.3",
"angular": "^1.4.2",
"jquery-ui": "1.11.4"
}
}
I tried adding an override to the bower.json file, but the result was the same.
The strange thing is that this works in node shell.
other possibly useful information:
Visual Studio 2015
NodeJS version: 0.12.2
gulp version: 3.9.0
wiredep versions: 2.2.2, 3.0.0-beta (tried both)
Found my mistake,
gulp.task('build:vendor', ['cleanVendor'], function () {
var files = require('wiredep')();
var stream = gulp.src(files.js);
// ...other code here
});
should be:
gulp.task('build:vendor', ['cleanVendor'], function () {
var files = require('wiredep')({ directory: 'bowerDirectoryHere'});
var stream = gulp.src(files.js);
// ...other code here
});
the default (I'm not sure where it is pulled from) was one level too high. The strange part is that it only fails on jquery-ui and not angular or others.

I cannot use 2 schemas with the same name in mongoose on 2 different connections because only one the first one is used?

var mongodbHost = 'mongodb://localhost:9000/';
var connectionA = require('mongoose').createConnection(mongodbHost + 'A', function(err){
var schema = require(path.resolve(__dirname, 'migrations', 'v01_00_001', 'models', 'index')).schemas.Serial;
debugger;
connectionA.model('Test', schema);
console.log('First check:', schema.statics.___XXX === connectionA.models.Test.___XXX);
}.bind(this));
var connectionB = require('mongoose').createConnection(mongodbHost + 'B', function(err){
var schema = require(path.resolve(__dirname, 'models', 'index')).schemas.Serial;
debugger;
connectionB.model('Test', schema);
console.log('First check:', schema.statics.___XXX === connectionA.models.Test.___XXX);
console.log('Second check:', schema.statics.___XXX === connectionB.models.Test.___XXX);
}.bind(this));
// output is true, false, false
// While it should be: true, false, true
Anybody knows what I might do?
The problem is that when I do the first require('mongoose') I get a new mongoose instance, therefore the rest of the requires will also get the same instance. And mongoose shares the schemas between connections :s
any help is appreciated,
thanks
Give the models different names, but still use the same collection name for both:
connectionA.model('TestA', schema, 'Tests');
...
connectionB.model('TestB', schema, 'Tests');
https://github.com/LearnBoost/mongoose/issues/1211
var mongooseA = new (require('mongoose').Mongoose)();
var mongooseB = new (require('mongoose').Mongoose)();
then create connection 2 connections...

Node.js consumption of json from Rails app

I have a json string (coming from my Rails app):
http://localhost:3000/employees/1.json
How do I get my Node.js app to consume this data?
This is the code I have in my Node.js app right now:
var employees = JSON.parse("http://localhost:3000/employees.json")
This is the error I'm getting:
prompt$ node app.js
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
SyntaxError: Unexpected token h
- at Object.parse (native)
- at Object. (/Documents/Coding/dustin/employees.js:19:22)
- at Module._compile (module.js:441:26)
- at Object..js (module.js:459:10)
- at Module.load (module.js:348:31)
- at Function._load (module.js:308:12)
- at Module.require (module.js:354:17)
- at require (module.js:370:17)
- at Object. (/Documents/Coding/dustin/app.js:34:17)
- at Module._compile (module.js:441:26)
See this question:
Using Node.JS, how do I read a JSON object into (server) memory?
You should read the file first and then parse it.
var employees = JSON.parse(fs.readFileSync('employees.json', 'utf8'));
If for some reason your Rails app runs on some other machine, you need to make a http request for that. You could try this:
var site = http.createClient(port, host);
var request = site.request("GET", pathname, {'host' : host});
request.end();
request.on('response', function(response) {
var json = '';
response.on('data', function(chunk) {
json += chunk;
});
response.on('end', function () {
employees = JSON.parse(json);
});
});

How to parse a XML string in a Firefox addon using Add-on SDK

I am trying to create a FF AddOn that brings some XML data from a website. But I can't find a way to parse my RESPONSE. First I used DOMParser but I get this error:
ReferenceError: DOMParser is not defined.
Someone suggested to use XMLHttpRequest, because the parsing is done automatically but then I get this other error:
Error: An exception occurred. Traceback (most recent call last):
File
"resource://jid0-a23vmnhgidl8wlymvolsst4ca98-at-jetpack/api-utils/lib/cuddlefish.js",
line 208, in require
let module, manifest = this.manifest[base], requirer = this.modules[base]; TypeError: this.manifest is undefined
I really don't know what else to do. I must note that I am using the AddOn Builder to achieve this.
Below the code that doesn't seem to work.
Option 1:
exports.main = function() {
require("widget").Widget({
id: "widgetID1",
label: "My Mozilla Widget",
contentURL: "http://www.mozilla.org/favicon.ico",
onClick: function(event) {
var Request = require("request").Request;
var goblecontent = Request({
url: "http://www.myexperiment.org/search.xml?query=goble",
onComplete: function (response) {
var parser = new DOMParser();
var xml = parser.parseFromString(response.text, "application/xml");
var packs = xml.getElementsByTagName("packs");
console.log(packs);
}
});
goblecontent.get();
}
});
};
Option 2:
exports.main = function() {
require("widget").Widget({
id: "widgetID1",
label: "My Mozilla Widget",
contentURL: "http://www.mozilla.org/favicon.ico",
onClick: function(event) {
var request = new require("xhr").XMLHttpRequest();
request.open("GET", "http://www.myexperiment.org/search.xml?query=goble", false);
request.send(null);
if (request.status === 200) {
console.log(request.responseText);
}
}
});
};
DOMParser constructor isn't defined in the context of SDK modules. You can still get it using chrome authority however:
var {Cc, Ci} = require("chrome");
var parser = Cc["#mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser);
nsIDOMParser documentation.
That said, your approach with XMLHttpRequest should work as well. You used the new operator incorrectly however, the way you wrote it a new "require object" is being created. This way it should work however:
var {XMLHttpRequest} = require("xhr");
var request = new XMLHttpRequest();
Please consider using an asynchronous XMLHttpRequest object however, use request.onreadystatechange to attach your listener (the xhr module currently doesn't support other types of listeners or addEventListener).
If you use XMLHttpRequest (available via the xhr module) you can easily avoid the use of DOMParser. Bellow I provide an example supposing request is an XMLHttpRequest object which request is successfully completed:
Instead of:
var parser = new DOMParser();
var xmlDoc = parser.parseFromString(request.responseText, "application/xml");
Use:
var xmlDoc = request.responseXML;
An then you can:
var packs = xmlDoc.getElementsByTagName("packs");
console.log(packs);
Or whatever.

Resources