can I test a javascript function using node.js - node.js

I suppose node.js allows us to test javascript code outside a browser. I am trying to test this function using node.js.
file print.js
var a = {
someProperty: 1
}
function printObject(){
process.stdout.write("hello: ",a);
}
When I try to run the above code as node print.js, nothing gets printed on the console. Why?

You would have to call the function like printObject(). You have just declared the function

Related

Using aws-sdk.js with require.js in a browser

I'm trying to figure out how to use the browser-based aws-sdk.js with require.js when building a web app.
If I try to build a class and include aws-sdk in the require.js define, once I try to create an instance and reference the AWS class, it says it is undefined.
For example, I have a function that checks to see if the credentials are an instance of AWS.Credentials and if not, it tries to initialize it with an STS token it retrieves via Rest.
The problem is, the code dies on the if(this.credentials instanceof AWS.Credentials) saying AWS is undefined. It even dies on my simple check of the needsRefresh.
This is what my define looks like - I'll include the 'needsRefresh' wrapper for an example of the sort of thing that is throwing the Undefined error:
define(['require','aws-sdk','jquery'],
function (require, AWS, $) {
// Aws helper class
function AwsHelper() { };
AwsHelper.prototype = {
credentials: null,
tokenNeedsRefresh: function () {
//////////////////////////////////////////////////////////////////
// errors out on the following line with: //
// TypeError: Cannot read property 'Credentials' of undefined //
//////////////////////////////////////////////////////////////////
if(this.credentials instanceof AWS.Credentials) {
return this.credentials.needsRefresh();
} else return true;
}
};
return AwsHelper;
}
);
I also tried the following format at the top of the file:
define(function (require) {
var AWS = require("aws-sdk"),
$ = require("jquery");
/* .. */
If I remove all onLoad references to the refresh code running, it will load and I can create an instance. But as soon as I call any function that references the AWS class, it dies.
How do I make sure that AWS class definition is still in global space once an instance is spawned?
Dunno what difference the paths will make (it's finding and loading the code just fine - I can see AWS Class in namespace in the debugger as it's loading but it's not in the namespace on the function call), but added on request:
requirejs.config({
baseUrl: '/js',
paths: {
lib: 'lib',
ImageUploader: 'ImageUploader'
}
});
I decided to try to play with this again and seemed to have figured out how I was going about it incorrectly. I have yet to integrate it back into my existing code setup, but I think I have a working solution.
The thing I was doing wrong was I was trying to set up the AWS class so I could load it as a module (thus why I tried wrapping it as the require.js suggested).
Playing with it this time around, I noticed something I hadn't before. I had an AWS that was undefined in the local scope and an other AWS that held the class definition in the global scope. So it was trying to specify AWS in my define that was creating the local 'null' version:
define(
["jquery","aws-sdk","dropzone","app/MyUtilities"],
function ($, AWS, Dropzone, MyUtilities) {
"use strict";
function MyClass() {};
return MyClass;
}
);
jquery and dropzone have whatever is needed to make sure they load that way, but aws-sdk seems to do some of it's own asynchronous loading. Thus the scope variable in the function is undefined.
Technically, it seems the only thing I needed defined as a module in the function wrapper is my own utilities module. So by switching it to:
define(
["app/MyUtilities","jquery","aws-sdk","dropzone"],
function (MyUtilities) {
"use strict";
function MyClass() {};
return MyClass;
}
);
... it seems $ and jquery are defined as needed, Dropzone is defined as needed and AWS is defined as needed. (and I don't get my errors when accessing the static AWS.config or AWS.Credentials definitions as I did before)

Electron app: Reference mainWindow object in another module?

I am building an electron app, where the mainWindow object is created following the quick start: http://electron.atom.io/docs/tutorial/quick-start/.
As per this quick start, it is created asynchronously. The problem that I run into, is that for instance when I want to send messages from main to renderer process, I need to reference the mainWindow object. If this happens to be in a module that I require, then I need a means to make this module know of the mainWindow object.
I could of course prepend it with global., but I know that this is very much advised against. So I wish to do it more elegantly.
I came across this post: Asynchronous nodejs module exports; which appears to offer a solution. Taking the main.js file from the quick start (see above link, it's explicitly shown there), it appears I would add to the createWindow function
if( typeof callback === 'function' ){
callback(mainWindow);
}
and export the main.js module as
module.exports = function(cb){
if(typeof mainWindow !== 'undefined'){
cb(mainWindow);
} else {
callback = cb;
}
}
Then, in a higher-level script, I would require as follows:
let main = require('./main.js');
let lib = require('./lib.js'); // Library where I need a mainWindow reference
main(function(window) {
lib.doSomething(window);
});
where lib.js looks like
module.exports.doSomething = function(window) {
// Do something with window object, like sending ipc messages to it
window.webContents.send('hello-from-main', "hi!");
}
Although the simple case in the original post 'Asynchronous nodejs module exports' works fine, I cannot get it to work like described above; running the app it complains Uncaught Exception: TypeError: Cannot read property 'webContents' of null. This is also the case if I directly require lib.js within main()'s callback (which I know is also advised against).
I confess that I do not fully understand the simple case of the post, as I am rather new to node. This prevents me from fixing my own implementation of it, which I agree is blunt copy/pasting which reasonably should be expected to fail. Could somebody help me with how to correct above method, or advise me of a different approach to make it work? Thank you!
I have created the npm package electron-main-window for the same.
Install:
$ npm install electron-main-window
or
$ yarn add electron-main-window
Usage:
// Import ES6 way
import { getMainWindow } from 'electron-main-window';
const mainWindow = getMainWindow();
// Import ES5 way
const mainWindow = require('electron-main-window').getMainWindow();
// e.g:
if(mainWindow !== null ){
mainWindow.webContents.send('mainWindowCommunication', "This is a test message");
}
Whooops! The devil is in the details... I had defined on top of main.js
let mainWindow = null, callback;
which caused the error! Should be
let mainWindow, callback;
then it works perfectly!
P.s. Instead of deleting my post, I opted for keeping it and answering myself for future reference of other people who need asynchronous exporting.

Best way to invoke code inside a module in nodejs

From a performance perspective, is there any difference between invoking code by wrapping it in a function and then exporting it:
function doSomething () {
// doing something here
}
module.exports = doSomething();
And just requiring it without any exports? like this:
myModule.js
// Code doing something
file that requires the module:
var doSomething = require('./myModule');
And if the purpose of the code inside the module is to run just once, do I need to store it in a variable?
If you don't need the return value of that function, then you don't have to store it in a variable.
The difference with:
function doSomething () {
// doing something here
}
module.exports = doSomething();
and using:
var x = require('module');
var y = require('module');
vs.
function doSomething () {
// doing something here
}
module.exports = doSomething;
and using:
var x = require('module')();
var y = require('module')();
is that in the first case, the function will be run only once, while in the second case the function will be run twice.
The difference is that if you just include it without module.exports, then the code will execute immediately but be private to the module. You can only access the data if you export it somehow, with module.exports. It can be either a function or a Javascript Object. Essentially, you can view everything within the module as being completely hidden from everything else in your application.
The only shortcut that I know of is for JSON files. If you look here: Module.exports vs plain json for config files, you can see that you can require('file.json') and it will replace the contents of the json file with a Javascript object that you can then use in your application.

Photoswipe and Require.js configuration

I have a module which is dependent upon both, PhotoSwipe and PhotoSwipeUI_Default. I am requiring both modules, like so and inside of my module I am initialising my gallery. EG:
define("modules/lightboxStart", ["vendor/PhotoSwipe", "vendor/PhotoSwipeUI_Default"], function (PhotoSwipe, PhotoSwipeUI_Default) {
var StartGallery = function(){
var lightBox = new PhotoSwipe($pswp, PhotoSwipeUI_Default, items, options);
lightBox.init();
}
StartGallery()
}
The gallery then works as expected but require is throwing a mismatched anonymous define module error in PhotoSwipe.js.
After looking through the docs I came to the conclusion that I need to run both scripts(PhotoSwipe and PhotoSwipeUI_Default) through the require.js API.
I then defined each, like so:
define('PhotoSwipe', function() {
//PhotoSwipe script here
return PhotoSwipe
})
And
define('PhotoSwipeUI_Default', function() {
//PhotoSwipeUI_Default script here
return PhotoSwipeUI_Default
})
This then eliminates the mismatched anonymous define module error I was getting earlier, but I am getting this error now instead:
PhotoSwipe is not a function
How could I fix this? I am essentially trying to access the PhotoSwipe function within PhotoSwipe.js and pass through my arguments but I am unable to do so without generating a load of js errors on the page and I can not figure out why.
Help much appreciated!
define( ["modules/lightboxStart", "vendor/PhotoSwipe", "vendor/PhotoSwipeUI_Default"], function (lightboxStart, PhotoSwipe, PhotoSwipeUI_Default) { //i think so}

Configuring $.ajax with backbone on node for testing with vows

(Edited to greatly simplify)
On node I have the following server.js file.
var Backbone = require('backbone');
var Tweet = Backbone.Model.extend({});
var Tweets = Backbone.Collection.extend({
model : Tweet,
url: function () {
return 'http://search.twitter.com/search.json?q=backbone'
}
});
var myTweets = new Tweets();
myTweets.fetch();
When I run this, I get an error that says. "Cannot call method 'ajax' of undefined" (1359:14)
basically that is the result of $ being undefined. Why is it undefined? Well there are a number of intermediate steps but when the file is loaded, it is expecting "this" to be "window" in browser or "global" on server. executed on node "this" = {}.
So the question, "How do I set 'this' to global" inside the backbone.js file?
On Backbone >= 1.x, you can simply assign Backbone.$ rather than using Backbone.setDomLibrary.
Solution for Backbone < 0.9.9
The first issue you need to address is how you are running this on Node anyway. Nodejs is a server-side JS environment, but it does not include any logic for controlling a DOM. For that you need to load something like JSDom.
When you have some DOM environment set up, you can load jQuery and your code into it and it should work just like a browser.
To answer your question specifically though, loading jQuery into the global is a bit of an ugly way to do it. You should use Backbone's setDomLibrary function to set $ to what you want.
Try something like this:
if (typeof exports !== 'undefined') {
MyModels = exports;
Backbone.setDomLibrary(require('jquery'));
server = true;
} else {
MyModels = this.MyModels = {};
}
This will fail if you try to do any DOM functions though.

Resources