In my Node.js project I am trying to import a module of helper functions. I am getting this error:
/home/Projects/my_app/helpers.js:3
var randomWeight = function(letters) {
^^^^^^^^^^^^ // <-- SyntaxError: Unexpected identifier with imported module Node.js
SyntaxError: Unexpected identifier
helpers.js:
module.exports = {
function randomWeight (letters) {
var total = letters.reduce(function (a, b) {
return a + b;
});
var r = (Math.random() * (0 - total) + total.tofixed(5));
var upto = 0;
for (var i = 0; i<=letters.length; i++) {
if ((upto + letters[i][0]) > r) {
return letters[i][1];
};
upto += letters[i][0];
};
}
/routes/index.js:
var express = require('express');
var router = express.Router();
var logic = require('../logic.js');
console.log(logic.letterSet)
I have tried lots of different variations of the import statement, with result in the module being imported as an empty object. From searching SO it appears this is usually because of a circular import, but I am sure I'm not importing logic.js anywhere else in my project (specifically /server.js.) I am new to Node so troubleshooting this has been sort of like shooting in the dark.
EDIT:
I seem to have solved the problem by importing the appropriate functions individually, like:
exports.letterSet = letterSet;
exports.randomWeight = randomWeight;
but I don't quite see how/why I can't import the whole module. I'm sorry if this seems like a ridiculous question but I am used to python where module imports are trivial.
you are returning an object {} in modules.exports, so you need to use object notation
module.exports = {
randomWeight: function (letters) {
var total = letters.reduce(function (a, b) {
return a + b;
});
var r = (Math.random() * (0 - total) + total.tofixed(5));
var upto = 0;
for (var i = 0; i<=letters.length; i++) {
if ((upto + letters[i][0]) > r) {
return letters[i][1];
};
upto += letters[i][0];
};
}
Related
My understanding of revealing module pattern is as follows:
CODE #1
const iifeModulePattern = (function () {
const secretSeed = 999; // ← private
const logSecretCode = function(){console.log(secretSeed+1)};
return {methodForPublic : logSecretCode};
})();
iifeModulePattern.methodForPublic();
So far I hope I'm not wrong. My question is:
Won't the following Code #2 serve same purpose?
If it does, why is Code #1 popular than Code #2?
If it doesn't, what's the difference?
CODE #2
const modulePattern = () => {
const secretSeed = 999; // ← private
const logSecretCode = function(){console.log(secretSeed+1)};
return {methodForPublic : logSecretCode};
};
modulePattern().methodForPublic();
I won't store "secret" codes (like passwords) in this way. The above codes are just examples.
const iifeModulePattern = (function() {
let value = 0; // private
return {
next: () => (value = 134775813 * value + 1) >>> 0
};
})();
for (let i = 0; i < 5; ++i) {
console.log("iifeModulePattern.next()", i, iifeModulePattern.next());
}
console.log("The basic IIFE.");
console.log("");
const modulePattern = () => {
let value = 0; // private
return {
next: () => (value = 134775813 * value + 1) >>> 0
};
};
for (let i = 0; i < 5; ++i) {
console.log("modulePattern().next()", i, modulePattern().next());
}
console.log("Kinda pointless this way, ain't it? Everytime, the sequence starts all over.");
console.log("");
const instance1 = modulePattern();
const instance2 = modulePattern();
for (let i = 0; i < 10; ++i) {
console.log("instance1.next()", i, instance1.next());
if (i & 1) {
console.log("instance2.next()", i, instance2.next());
}
}
console.log("This usage makes more sense.\nAnd the two instances progress independant of each other.");
.as-console-wrapper {top:0;max-height:100%!important}
Won't the following Code #2 serve same purpose?
Yes, No, maybe; it depends on how you use it.
If it doesn't, what's the difference?
iifeModulePattern is a singleton, modulePattern() is a factory.
If it does, why is Code #1 popular than Code #2?
What's the purpose of giving the factory a name, store it in a variable if all you'll ever do is to call it once, right here, right now?
I'm trying to reduce the amount of global variables that my application uses, but I'm stuck trying to figure out how to structure my files.
This is the structure of the current application with some example variables and functions:
var x = 0;
var y = 1;
var z = 2;
foo = function(n) { return n + 1; }
bar = function(n) { return foo(n) * 2; }
This is the structure I'm moving to:
var app = new function() {
var x = 0;
var y = 1;
var z = 2;
foo = function(n) { return n + 1; }
bar = function(n) { return foo(n) * 2; }
}
Is there a way to define these variables and functions in other files (or in the same file but outside the function) and add them to the application namespace? I have a lot of variables and functions to define, and I just want to move everything from the global namespace to the application namespace in a way that all the variables and functions can continue to access each other. I also need to put them into multiple files, because I don't want to have an application file that's thousands of lines long.
Adding variables and functions to the application by making them properties (using 'app.functionName') would mean I would need to change how functions reference each other, and it doesn't seem like the right way to do it. For example, I couldn't just do this:
app.foo = function(n) { return n + 1; }
app.bar = function(n) { return foo(n) * 2; }
I would have to do this:
app.foo = function(n) { return n + 1; }
app.bar = function(n) { return app.foo(n) * 2; }
I can do the same with variables (using 'app.variableName'), but the same issue arises in that I can't just reference the variable anymore without putting 'app.' in from of the variable.
Maybe the structure of my application is just terrible and this isn't the way things are meant to be done in Javascript, but I can't seem to figure out how to implement my application without using lots of global variables or without just putting everything into one function in one file.
A more modern way would be to use a block statement and const to scope it locally to that:
var app = app || {};
{
const foo = app.foo = n => n + 1;
const bar = app.bar = n => foo(n) * 2;
}
The same can be achieved in older js with an IIFE:
var app = app || {};
(function() {
var foo = app.foo = function(n) {
return n + 1;
};
var bar = app.bar = function(n) {
return foo(n) * 2;
};
})();
Now you can put multiple js files with that structure into one page and then communicate with each other via app.sth().
This is still not really clean and you got a lot of boilerplate code. Therefore tools like Webpack were invented, so you can just write:
// Foo.js
export default function foo(n) { return n + 1 }
// Bar.js
import foo from "./foo";
export default function bar(n) { return foo(n) * 2; }
And webpack will generate you one tiny little (unreadable) js file out of it.
I hope I'm asking the question correctly, but essentially, is there a way in NodeJS to have a CommonJS module return a stream of data instead of a finalized chunk of data after a (long) computation? Assuming there is more than one way, what are those techniques?
For example, say I have a findPrimes function, written as a CommonJS module:
find-primes.js
/**
* #module findPrimes
* #param {int} n - Find all primes less than this number
* #return {array}
*/
module.exports = function(n) {
if (n < 2) {
return [];
} else if (n === 2) {
return [2];
}
var primes = [2];
for (let i = 3; i < n; i += 2) {
let is_prime = true;
let sq = Math.ceil(Math.sqrt(i));
for (let t = 2; t <= sq; t++) {
if (i % t === 0) {
is_prime = false;
break;
}
}
if (is_prime) {
primes.push(i);
}
}
return primes;
};
As you can see, this function returns an array of all the prime numbers less than its input. It returns the array after it has computed all those numbers.
So, say I go to use this module in a node script
index.js
const primes = require('./find-primes.js');
// Usage: `node index.js <num>`
let primes_less_than = process.argv[2];
console.log(primes(primes_less_than));
When I run the above script with an arg of 25, I get the following (expected) output:
$ node index.js 25
[ 2, 3, 5, 7, 11, 13, 17, 19, 23 ]
However, say I passed in a much larger number, like 10,000,000
$ node index.js 10000000
# Takes a while to run before outputting the numbers...
While this works, ideally I'd like the program to start writing out the numbers it has computed before it finishes.
So my program would still take a while to run, but it would start outputting information to the screen much faster than "compute EVERYTHING first, then output ALL results".
What is the best way to achieve this effect? Streams? Promises?
I'm open to any and all techniques for this, thanks.
You'll have to use the Stream class from nodejs, and the method should export a callback with a stream as the commentaries said:
const stream = require('stream');
function getPrimesStream(n, cb) {
const primesStream = new stream.Stream();
cb(null, primesStream);
if (n >= 2) {
primesStream.emit('data', 2);
}
const primes = [2];
for (let i = 3; i < n; i += 2) {
let isPrime = true;
const sq = Math.ceil(Math.sqrt(i));
for (let t = 2; t <= sq; t += 1) {
if (i % t === 0) {
isPrime = false;
break;
}
}
if (isPrime) {
primesStream.emit('data', i);
primes.push(i);
}
}
return primes;
}
getPrimesStream(1000, function (err, stream) {
stream.on('data', function (data) {
console.log(data);
});
stream.on('end', function() {
console.log('finished');
});
});
You may use Node.js's stream module for this. It's hard to answer your question within a few lines of code, but if you are really interested in how streams work, have a look at this video (this is me giving a talk about Node.js streams at the Node.js meetup in Munich, Germany).
Alternatively, you may use a generator function with yield, but this as well is hard to explain from scratch in a few lines.
Anyway, streams and generator functions are the terms you should look for.
This code gets the data required from the python code, which in turn fetches the list of objects from aws s3. it gets the code using stdout. I've managed to break the string i fetch from python, tokenize it and put it in an javascript array. The issue lies when i try to put it in the collection using the code below. It shows garbage values have been put into the collection.
here is the python code
import sys
import boto
from boto.s3.connection import S3Connection
AWS_KEY = '##################'
AWS_SECRET = '*********************************'
REGION_HOST = 's3.ap-south-1.amazonaws.com'
aws_connection = S3Connection(AWS_KEY, AWS_SECRET, host=REGION_HOST)#,
bucket = aws_connection.get_bucket('####3')
z = 0
stp = ""
for file_key in bucket.list():
p = file_key.name
y = p.split("-")
for a in y:
z = z + 1
if(z % 2 == 0):
stp = stp + a + " "
z = 0
print(stp)
sys.stdout.flush()
Here is the java script code.
The python code is called by the javascript
i get back the string in javascript by stdout.
I split the string store it in a variable in javascript.
Problem is that i dont know how exactly i am supposed to insert in my collection.
Garbage = new Mongo.Collection("garbag");
if (Meteor.isServer) {
var exec = Npm.require('child_process').exec;
var Fiber = Npm.require('fibers');
var Future = Npm.require('fibers/future');
var out;
var arr;
var a = 3
Meteor.methods({
callPython: function() {
var fut = new Future();
exec('python /home/piyush/pycloud/v1.py', function (error, stdout, stderr) {
if (error) {
throw new Meteor.Error(error, error);
}
if (stdout) {
console.log(stdout);
out = stdout;
arr = out.split(" ");
for(i = 0; i < 10; i++){
console.log(arr[i]);
}
}
if (stderr) {
console.log("mital");
}
new Fiber(function() {
fut.return('Python was here');
}).run();
});
console.log("miitttaall");
console.log(arr);
if(a < 5){
var crr = [{area: "pashan" , amount : arr[0]},
{area: "balewadi", amount : arr[1]},
{area: "aundh" , amount : arr[2]}];
_.each(crr , function(doc){
Garbage.insert(doc);
});
console.log("willthisprint");
}
return arr;
},
});
}
My following code:
var AWS = require('./aws-sdk-2.2.10.js') // THIS LINE ERRORS
Produces the follwing error:
Uncaught TypeError: Cannot read property 'crypto' of undefined
This is the part of aws-sdk-2.2.10.js that is throwing the error
...
65: [function(require, module, exports) {
(function() {
var _global = this; // I think 'this' is undefined here
var mathRNG, whatwgRNG;
mathRNG = function(size) {
var bytes = new Array(size);
var r;
for (var i = 0, r; i < size; i++) {
if ((i & 0x03) == 0)
r = Math.random() * 0x100000000;
bytes[i] = r >>> ((i & 0x03) << 3) & 0xff;
}
return bytes;
}
;
if (_global.crypto && crypto.getRandomValues) { // THIS LINE ERRORS
whatwgRNG = function(size) {
var bytes = new Uint8Array(size);
crypto.getRandomValues(bytes);
return bytes;
}
;
}
module.exports = whatwgRNG || mathRNG;
}
)();
}
...
My code is built via webpack and my code lives in the entry file, app.js.
I'm not sure why this wouldn't work?
Edit: If it matters, my end goal is to use Parse's CloudCode to put and get files from s3