meteor / javascript function not working when in another file - javascript

This is interesting.
I have a file structure as such:
/
/client/
/server/
The app I'm working on is working fine, I have many .js files in the /client/ folder, all separated into logical (to me) sections. They work fine when compiled.
I have added a new file though, called miscFunctions.js to the mix and added a simple function and saved:
function sessionDataReset(){
//Set the New Organisation Session data to be false, meaning we're not adding a new organisation
return Session.set('addingOrganisation', false);
};
This function, when called returns the following error:
Uncaught ReferenceError: sessionDataReset is not defined
When I move that exact code though to the .js file I'm calling it from it works fine.
Why is the error happening as I was of the understanding what I'm trying to do can be done with Meteor?
Any advice greatly appreciated.
Rob

First try declaring your file this way:
sessionDataReset = function() {
//Set the New Organisation Session data to be false,
//meaning we're not adding a new organisation
return Session.set('addingOrganisation', false);
};
This ensures the function will be visible globally.
(#user1623481 Meteor wraps files as IIFE's when it compiles them, creating a function scope that was limiting the visibility of this function.)
This will most likely resolve it, but following this check the file load order in the Meteor Docs

Related

Functions included from the prototype in a javascript class are not seen in the editor's autocomplete

I have the following problem, I have created a library. which its methodos
they are in separate files writeLog.js in a folder called ./lib.
and I have an index.js file that explores that folder and extracts the function
and puts the same name as the file as the function name.
example:
writeLog.js
and then I can use
let jsPackTools require('./index');
let utils = new jsPackTools();
utils.writeLog('test');
The way I use to add the methods to the classes is through the prototype.
the folder is scanned with readdirSync () and then I take the file name to
place it inside a require ().
the code is the following:
fs.readdirSync(__dirname+'/lib').forEach(modules => {
let module = modules.split('.').shift();
jsPackTools.prototype[module] =require(\`${__dirname}/lib/${module}\`);
});
Everything works perfectly fine, the problem is that when I want to access my methods through the autocomplete of any code editor. Methods they seem to be not accessible. however everything works perfectly, I can do use of functions.
    
The problem is that I have to know each method that I am going to use and it cannot be visualized in the completed auto of any editor.
I have tried with:
const writeLog = require('./lib/writeLog');
class jsPackTools {
get writeLog() { return writeLog.bind(this) }
}
This allows indexing perfectly. however, I don't logo do it dynamically.
The idea is that the class does not know what its methods are until the ./lib folder is scanned and all methods are extracted. This way you can add functions inderteminately and when you use them you can see.
    
I do not want to use transpilators, I thought of using a d.ts but it is necessary to use typeScript but the intention is to create this library without dependencies or the least possible.

Trouble calling js functions with prepack.io

I have this function in a js file (not really spectacular):
function loadLazyImages() {
var lazyImages = document.querySelectorAll('.js-lazyload');
}
loadLazyImages();
I also have a gulp task that concatenates and uglifies this file among others. This worked fine in the past, but now I'm trying out 'prepack' and there seems to be a problem:
not an object
TypeError
at loadLazyImages (unknown:12:22)
at unknown:15:1
C:\...\node_modules\prepack\lib\prepack-standalone.js:59
throw new InitializationError();
The documentation states something about document and window not being defined but is rather vague when it comes tot solutions. Any insights?
Try run prepack with --trace option.

Accessing `goog.require`d object in closure library without compilation

I'm experimenting with the google closure library, and am working through the
official XhrIo guide.
I ran into some trouble with the xhr-quick2.js example, reproduced below:
goog.require('goog.net.XhrIo');
var xhr = new goog.net.XhrIo();
goog.events.listen(xhr, goog.net.EventType.COMPLETE, function(e) {
obj = this.getResponseJson();
log('Received Json data object with title property of "' +
obj['title'] + '"');
alert(obj['content']);
});
function getData(dataUrl) {
log('Sending simple request for ['+ dataUrl + ']');
xhr.send(dataUrl);
}
When run, I receive the error:
Uncaught TypeError: Cannot read property 'XhrIo' of undefined
If I move the event listener and xhr instantiation to within the getData
function (which is called in the body's onload), all is well.
goog.require('goog.net.XhrIo')
function getData(dataUrl) {
var xhr = new goog.net.XhrIo()
goog.events.listen(xhr, goog.net.EventType.COMPLETE, function(e) {
obj = this.getResponseJson()
log(`Received Json data object with title property of "${ obj["title"] }"`)
alert(obj["content"])
})
log(`Sending simple request for [${ dataUrl }]`)
xhr.send(dataUrl)
}
function log(msg) {
document.getElementById('log').appendChild(document.createTextNode(msg));
document.getElementById('log').appendChild(document.createElement('br'));
}
I assume this is because goog.require hasn't finished importing net when
goog.net.XhrIo is instantiated on line 3 of the first code sample. I suppose
the ideal solution is to run all my code through the closure compiler, but I'm
just experimenting and other parts of the
documentation
imply my workflow is acceptable for development.
Is there anything I can manually source in my html that would eliminate this
problem? Is there some other approach I should take?
It's been a few years since I last played with closure, but I don't think you can just use require without the dependency compiler.
Closure works by scanning your JavaScript files for goog.module and goog.require to write a deps.js file. This file has to be loaded first before your JavaScript files. It lists all the modules used by the code and loads them in the correct order.
If deps.js comes first, then goog.net will be loaded in by the time it gets to your code. The code goog.require('goog.net.XhrIo') on line 1 will at this time be ignored.
According to the docs the goog.require will insert a <script> tag after the current <script> being executed. So if you want to skip the step of using deps.js then you'll have to wrap everything in a document ready callback, or manaully add goog.require to a JavaScript file that is loaded before your code.
I think it's not worth the effort and easier to just use the closure dependency writer to create the deps.js file.
There's a quick tutorial here:
https://www.safaribooksonline.com/library/view/closure-the-definitive/9781449381882/ch01.html
Here's the CLI for writing the deps.js file:
python ../closure-library/closure/bin/calcdeps.py \
--dep ../closure-library \
--path my_stuff.js \
--output_mode deps > deps.js
For uncompiled mode, the required document must be pre-loaded. So in your html document you would have:
<!DOCTYPE html>
<html>
<head>
<script src="path/to/closure/base.js"></script>
<script>
goog.require('goog.net.XhrIo');
</script>
<script src="mysource.js"></script>
</head>
</html>
Any dependencies must be loaded in a separate script tag. Then your code samples above should work.

Include libraries in Protractor test case

I would like to include a module/library in a protractor test case, however, as soon as I add the line
var lib = require('./loginactions.js');
All the references to protractor and related objects are lost. In other words, if I don't have the require line, the 'protractor' and 'browser' variables are found and test runs fine (using the functions within the file), but after adding that line the variables are not found any more.
Here is a minimal test case:
var lib = require('./loginactions.js'); //problematic line
describe('Login / Logout to Application',function(){
var ptor;
beforeEach(function(){
ptor = protractor.getInstance(); //protractor reference lost
browser.get('http://localhost:80'); //browser reference lost
});
it('should login and then logout successfully', function(){
//Do things here
lib.login(user, pass, ptor);
});
});
I export the functions in this way:
module.exports.Login = Login;
module.exports.Logout = Logout;
//Params: ptor - protractor instance
function Login(user, pass, ptor)
{
//stuff
}
function Logout(ptor)
{
//stuff
}
I also wonder, is this even the correct way of including the own libraries into the project. So my question is, how to properly include libraries into a protractor test case?
To answer my own question, using protractor as a library method worked, this way the references to protractor were restored. So adding these two requires solved my issue:
var protractor = require('/path/to/protractor');
require('/path/to/protractor/jasminewd');
So my test looked similar to the updated code in
'no method expect' when using Protractor as a library question.
However, I am not entirely sure about the global browser object. It is a wrapper around the WebDriver object according to http://www.ng-newsletter.com/posts/practical-protractor.html, but so is protractor instance. So I decided to replace all 'browser' variables with 'ptor' and so far no complaints. This may backfire, but as I said, I'm not entirely sure whether the global browser object that is created along with the global protractor object, when running protractor normally and not as library.

How to include Javascript objects in a Jade template before Jade compilation

I am working with a website built with Jade/Express for a few weeks now. I recently organized the image folder for the website so all the images were disbursed between several folders to make it easier to use and sort through.
To make it easier to make changes to the hierarchy of images (and other such files) I wrote a script that contains some globals for file paths. Now I have been trying to get the script to run so that I can call functions inside the jade template to automatically use these globals.
For example. Images are now sorted into several folders:
File Hierarchy
img/
glyphs/
interactivity/
buttons/
...
In my path manager script, I created several functions, including the following:
In: path-manager.js
images_root_path = "/img/";
glyph_path = images_root_path + "glyphs/";
function getGlyph(color, name) {
return glyph_path + color + "/" + name;
}
I tried several methods to get the script to execute before the template. Here is one of the attempts:
In page.jade
include ../../../public/js/lib/path-manager.js
=NamespacePathManager();
The above is, in theory, supposed to include the js and then I execute the namespace below to make the functions available, but that isn't working.
This is a portion of the Jade template that I want to use the function in:
In page.jade after the script include
span.challenge-time
img(src=getGlyph("black","stopwatch.png"), style="margin-right:5px;")
The above example should return: "/img/glyphs/black/stopwatch.png"
The problem is, I believe, that the scripts I am trying to make available server-side to the jade template are not being executed before the jade template is rendered. Everything I have tried doing to get this to work always results in an error saying that the server doesn't recognize the function getGlyph or when I started using the namespace function, NamespacePathManager
Summary: I want a javascript file to execute before a jade template is rendered into a webpage so that I can call functions and variables from that javascript on the server to use while rendering the jade template. My problem is that all the methods I have tried are unable to execute the javascript before the Jade is rendered.
Update
One work around I found was to put the javascript into unbuffered code directly on the page including a jade. This isn't quite the elegant solution I was looking for, but it works for now
- some code
- more code
This code is executed inline. The downside is that I have to include it on every page manually - instead of just including it once and having the functions available everywhere.
You can register helper methods in Express that will then be accessible in the views.
So in your case, the path-manager.js can be the helper file that you register, and contains:
var images_root_path = "/img/";
var glyph_path = images_root_path + "glyphs/";
exports.helpers = {
getGlyph: function (color, name) {
return glyph_path + color + "/" + name;
}
// Other helper methods here..
};
Then when setting up the express server, you register the helper
var app = express.createServer();
// app.configure here...
// app.use ...
app.helpers(require('./path-manager.js').helpers);
// Routes set up here ..
Finally, you can call the helper method from Jade view like this:
span.challenge-time
img(src='#{getGlyph("black","stopwatch.png")}', style='margin-right:5px;')
There's a good write up on this topic at DailyJS http://dailyjs.com/2011/01/03/node-tutorial-8/

Categories