unexpected strict mode reserved word -- yield? Node v0.11, harmony, es6 - node.js

Trying to use a new ES6 based node.js ODM for Mongo (Robe http://hiddentao.github.io/robe/)
Getting "unexpected strict mode reserved word" error. Am I dong something wrong here?
test0.js
"use strict";
// Random ES6 (works)
{ let a = 'I am declared inside an anonymous block'; }
var Robe = require('robe');
// :(
var db1 = yield Robe.connect('127.0.0.1');
Run it:
C:\TestWS>node --version
v0.11.10
C:\TestWS>node --harmony test0.js
C:\TestWS\test0.js:12
var db1 = yield Robe.connect('127.0.0.1');
^^^^^
SyntaxError: Unexpected strict mode reserved word
at exports.runInThisContext (vm.js:69:16)
at Module._compile (module.js:432:25)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:349:32)
at Function.Module._load (module.js:305:12)
at Function.Module.runMain (module.js:490:10)
at startup (node.js:123:16)
at node.js:1031:3

If you want to use generators to do asynchronous operation in synchronous fashion you must do it like:
co(function*() {
"use strict";
{ let a = 'I am declared inside an anonymous block'; }
var Robe = require('robe');
var db1 = yield Robe.connect('127.0.0.1');
})();
where co realization you can find in:
co
Task.js
bluebird's Promise.coroutine
q's spawn
and so on.
In strict mode you cannot use yield outside of the generators. In non-strict mode outside of the generators yield will be considered as variable identifier - so in your case it'll throw an error anyway.

Also noteworthy... new versions of co return/use promises rather than thunks. So this is what worked with newer versions of co.
var co = require('co');
co(function*() {
"use strict";
{ let a = 'I am declared inside an anonymous block'; }
var Robe = require('robe');
var db1 = yield Robe.connect('127.0.0.1/swot');
console.log(db1)
return db1;
}).then(function (value) {
console.log(value);
}, function (err) {
console.error(err.stack);
});

Related

Reference a global JS function in another file, in NodeJS

What I'm actually doing is writing a VS Code Extension, but since I'm new to Node I'm struggling with referencing one JS file from another.
//main.js (compiled from TypeScript)
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
require("./Test.js");
console.log("hello");
t1();
and
//Test.js
function t1() {
console.log("t1");
}
They're both in the same folder. If I run it from VS Code, or from node directly, it doesn't work
PS E:\VSCodeTest> node src/main.js
hello
E:\VSCodeTest\src\main.js:5
t1();
^
ReferenceError: t1 is not defined
at Object.<anonymous> (E:\VSCodeTest\src\main.js:5:1)
at Module._compile (module.js:635:30)
at Object.Module._extensions..js (module.js:646:10)
at Module.load (module.js:554:32)
at tryModuleLoad (module.js:497:12)
at Function.Module._load (module.js:489:3)
at Function.Module.runMain (module.js:676:10)
at startup (bootstrap_node.js:187:16)
at bootstrap_node.js:608:3
The VS Code project is actually TypeScript but I've distilled it down to the crux of the problem in the JS files.
I believe it should work based on
https://www.typescriptlang.org/docs/handbook/modules.html
Import a module for side-effects only Though not recommended practice,
some modules set up some global state that can be used by other
modules. These modules may not have any exports, or the consumer is
not interested in any of their exports. To import these modules, use:
import "./my-module.js";
How have I misunderstood that?
Change Test.js to this:
//Test.js
function t1() {
console.log("t1");
}
module.exports = t1;
And then do something more like this in main.js:
const t1 = require("./Test.js");
t1(); // prints "t1"
There's a lot of information about how modules work in the docs: https://nodejs.org/api/modules.html
Alternatively, if you want t1 to be a global, then assign it to global.t1 in Test.js:
//Test.js
global.t1 = function t1() {
console.log("t1");
};
I wouldn't recommend that if you can avoid it, though, for all the reasons people recommend avoiding globals when possible
Require doesn't work quite like that, but you're close -- if you want to use a function you've created to in another file, just add it to that file's exports.
/// test.js
exports.t1 = function() ...
// or
module.exports = {
t1: function() ...
}
Then you need to specifically save that off to use it
/// main.js
var t1 = require('./test.js').t1;
t1();
Global scoping doesn't work like it does in the browser, check out node's docs on it, or try a blog explaining it (I didn't write this and can't fully vouch)

Node 5.10 spread operator not working

According to the docs, the latest node (Node 5+) should support the spread operator by default, like so:
const newObj = {
...oldObj,
newProperty: 1
}
And I have node 5.10.1 installed (e.g. that's what 'node -v' tells me). But I am still getting this error:
c:\[myprojectfolder]>node index.js
c:\[myprojectfolder]\index.js:21
...oldObj,
^^^
SyntaxError: Unexpected token ...
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:387:25)
at Object.Module._extensions..js (module.js:422:10)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Function.Module.runMain (module.js:447:10)
at startup (node.js:146:18)
at node.js:404:3
What am I missing?
The array spread syntax is supported, but the object spread syntax is not - this is most likely due to it not being finalized as part of the ECMAScript spec yet (it was originally planned for inclusion in ES7/ES2016, but it got bumped back, if I recall correctly).
Your options in the meantime are either to use a transpiler (such as Babel, with the transform-object-rest-spread plugin), or if that feels like overkill, you can use the new built-in Object.assign function. The object spread syntax is effectively just syntax sugar around Object.assign - the example in your question could be expressed like so:
const newObj = Object.assign({}, oldObj, {
newProperty: 1
});
Note the empty object as the first argument; the properties from the rest of the passed objects get merged into it, with those furthest to the right of the function call taking priority. It may seem more intuitive to simply have oldObj as the first argument, but this doesn't have quite the same effect - it would mutate the existing oldObj as well as returning it. Having an empty object as the target leaves oldObj unchanged.
Update: As of Node 8.6, object spread syntax is supported.
Update 2: Object spread syntax has finally made its way through the proposal process, and will be part of the ES2018 spec.
What you tried to use is called object spread and is not part of the es2015 specification. Node only supports the regular spread in function calls and array literals. Unfortunately not even array destructuring is supported yet, although they link to the MDN page which describes both structuring and destructuring use of ....
You can use Object.assign instead:
const newObj = Object.assign({}, oldObj, {
newProperty: 1
});
That's works in Node.js 8.5.0.
Example:
var oldObj = {
oldProperty: 0
}
var newObj = {
...oldObj,
newProperty: 1
}
console.log('Old Object: ' + JSON.stringify(oldObj, null, ' '))
console.log('New Object: ' + JSON.stringify(newObj, null, ' '))
Output:
Old Object: {
"oldProperty": 0
}
New Object: {
"oldProperty": 0,
"newProperty": 1
}
Screenshot from IDE Debug Console:

Chai.should() makes Mocha explode

I try to use Chai Should style assertions, but the following statement makes Mocha explode. Here is my complete Require block:
/**
* Module dependencies.
*/
var mongoose = require('mongoose'),
User = mongoose.model('User'),
moment = require('moment'),
SSEvent = mongoose.model('Event'),
chai = require('chai');
chai.use(require('chai-datetime'));
var should = chai.should();
Error message:
Running "mochaTest:src" (mochaTest) task
>> Mocha exploded!
>> TypeError: chai.should is not a function
>> at Object.<anonymous> (/Users/sebastianweikart/Desktop/dev/conftool-nga-mean/modules/events/tests/server/events.server.model.tests.js:13:19)
>> at Module._compile (module.js:413:34)
>> at Object.Module._extensions..js (module.js:422:10)
>> at Module.load (module.js:357:32)
>> at Function.Module._load (module.js:314:12)
>> at Module.require (module.js:367:17)
>> at require (internal/module.js:16:19)
>> at /Users/sebastianweikart/Desktop/dev/conftool-nga-mean/node_modules/mocha/lib/mocha.js:219:27
What could possibly be the problem?
I use
"chai": "^3.5.0" and "mocha": "~2.4.5" which should be the latest stable versions..
Update:
I now added the following simple stripped down test - and it still explodes:
'use strict';
/**
* Module dependencies.
*/
var chai = require('chai');
var should = chai.should();
/**
* Unit tests
*/
describe('Chai Should Test', function () {
describe('Chai Should() should work', function () {
it('Chai Should() must work', function (done) {
var spartacus = 'spartacus';
should.exist(spartacus);
done();
});
});
});
Running "mochaTest:src" (mochaTest) task
>> Mocha exploded!
>> TypeError: chai.should is not a function
>> at Object.<anonymous> (/Users/sebastianweikart/Desktop/dev/conftool-nga-mean/modules/events/tests/server/chai.should.test.js:7:19)
make sure should.js is uninstalled in the project. Conflict occurs when should.js and chai.should is used together
Make sure you are not also requiring the should package -> https://www.npmjs.com/package/should.
If you are correctly importing chai it doesn't seem as if there's a problem.
The chai docs state:
With the should require, the function is [...] executed.
So if you have a valid chai object, it will have a shoudld() function attached. You can verify this by testing it live on tonic dev.
You should also try to remove the chai.use(require('chai-datetime')); statement - this could be overriding chais original properties and removing the should() function.
If you are still having problems it is likely being caused by something else - in which case we'd need to see / know more about your project.
I had the same problem.
But I just imported should in this way const should = chai.should; instead of const should = chai.should();
I used
chai.Should()
instead of
chai.should()
as a temporary fix, since the project I'm working on currently requires a package that requires the should package, which interferes with chai. Chai exports with both .should and .Should, and they refer to the same function, loadShould() which is what we're invoking.

Unexpected token =

I'm unsure as to what could cause this error in Node.js, as I've never seen it before and cannot find another issue online.
Message:
Unexpected token =
Stack:
SyntaxError: Unexpected token =
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:404:25)
at Object.Module._extensions..js (module.js:432:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:311:12)
at Module.require (module.js:366:17)
at require (module.js:385:17)
at Object.<anonymous> (/Projects/api/test/integration/models/article.js:3:15)
The file that is causing the error has the following contents:
'use strict';
var Article = require('../../../models/article')
Why in the world would = cause an error?
Edit 1 - adding the article.js that is being required:
'use strict';
class ArticleModel {
constructor(options = {}) {
this.options = options
}
}
module.exports = ArticleModel
node.js 5.0 does not support all ES6 features yet. In particular, it does not yet support default parameters.
So this line:
constructor(options = {}) {
is what is causing the error with the = assignment.
See this table for which features are supported in node.js 5.0.
You can replace the default parameter assignment with the old fashioned method:
constructor(options) {
this.options = options || {};
}
I think, your current Node.js distribution doesn't support default parameter values.
You should remove it:
constructor(options) {
this.options = options || {};
}
Or, try to play with --harmony runtime flag.
According to this link --harmony can not to help, this feature doesn't implemented in node5.0 at all.
I am using Node v5.7.0 and can enable default parameters using this option:
--harmony-default-parameters
The error is on the 3rd line of article.js.

mongodb with nodejs

this is th code I am using inserting a document to mongodb.
var client = new Db('test', new Server("127.0.0.1", 27017, {}), {w: 1}),
test = function (err, collection) {
collection.insert({a:2}, function(err, docs) {
collection.count(function(err, count) {
test.assertEquals(1, count);
});
// Locate all the entries using find
collection.find().toArray(function(err, results) {
test.assertEquals(1, results.length);
test.assertTrue(results[0].a === 2);
// Let's close the db
client.close();
});
});
};
client.open(function(err, p_client) {
client.collection('test_insert', test);
});
but while running I am getting error
xports, require, module, __filename, __dirname) { var client = new Db('test',
^
ReferenceError: Db is not defined
at Object. (C:\Users\Basic node\cheerio\mongonode.js:1:81
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.runMain (module.js:492:10)
at process.startup.processNextTick.process._tickCallback (node.js:244:9)
can you suggest me how to solve this problem
thanks in advance
Please import all the required modules, which you are using. Db is not defined points out that Db is defined in some other module or you have forgot to declare it.
You'll notice this exact code block posted in a number of different stackoverflow questions. The problem here is that this is a copy and pasted code block from mongodb's documentation, as is in fact the first example of a mongodb nodejs program.
https://npmjs.org/package/mongodb
You'll find this under "Introduction" as "A simple example of inserting a document."
It's clearly an incomplete example, but a lot of people are just trying it out to see if they've got everything installed correctly and immediately run into a wall.
Most people will have installed the mongodb driver, but will be missing something at the top like this:
var mongodb = require('mongodb');
var Db = mongodb.Db;
var Server = mongodb.Server;
I also fell into the copy-paste trap here and ran into another issue with the "assertEquals" method not existing. I've seen other people reference that function in other places on the web, but not really sure how it works.
In any case, to make it work for me, I required the assert module:
var assert = require('assert');
And then I replaced the assertEquals lines with something like this:
assert.equal(1, count, "Unexpected result");
Note that you're going to run into an issue if you've run this a couple of times; it's going to count the number of things in that table, and there is going to be more than one.
You'll have to figure out how to get into mongo's CLI and remove them to get it to run successfully.
Try to install mongodb native driver
npm install mongodb

Resources