Lightswitch HTML global JS file to pass variable - javascript

I know how this works in C#, however not so much in javascript so I am hoping it is similar.
With Javascript can I create say a master.js, with a variable (var defaultValue = "1234"), which I can reference in all other javascript files associated with the project?
so in terms of Lightswitch HTML, each screen has the ability to have a js file, and on the screen I want to be able to retrieve this defaultValue.
Can this be done?
If yes, how can I get this value onto the current screen?
so far I have created a main.js file, added this function:
function getDefaultValue(value) {
var value = "1234";
return value;
}
and declared the js file in the default.htm file:
<script type="text/javascript" src="Scripts/main.js"></script>
I know this is how i am using other JavaScript files like blob.js, lsWires.js etc...
using this method in by screen.js doesn't work so one of these stages is causing an error...
window.alert(main.getDefaultValue(value));
ideally i would like to use this defaultvalue for setting a value, i.e. var test = main.getDefaultValue(value)

This is certainly possible, and the script declaration you've used in your default.htm appears correct.
However, as the approach you've described creates a global getDefaultValue function (added to the global window object context) you wouldn't specify a main 'namespace' prefix like you would in c#.
Instead, rather than calling the function using main.getDefaultValue, you'd use the the following approach within your LightSwitch screens:
myapp.BrowseProducts.created = function (screen) {
window.alert(window.getDefaultValue("123")); // This will display 1234
// As window is a global object, its window prefix can be omitted e.g.
alert(getDefaultValue("123")); // This will display 1234
};
Or, if you want to define a global defaultValue variable in your main.js (probably the approach you're looking to implement) you would have the following code in your main.js file:
var defaultValue = "5678";
Then you'd access it as follows in your LightSwitch screens:
myapp.BrowseProducts.created = function (screen) {
alert(defaultValue); // This will display 5678
defaultValue = "Hello World";
alert(defaultValue); // This will now display Hello World
};
Also, if you'd like to organise your functions/properties in a main 'namespace', you could use the following type of approach in your main.js file: -
var main = (function (ns) {
ns.getDefaultValue = function (value) {
var value = "1234";
return value;
};
ns.defaultValue = "5678";
return ns;
})(main || {});
These would then be called as follows in your LightSwitch screens: -
myapp.BrowseProducts.created = function (screen) {
alert(main.getDefaultValue("123")); // This will display 1234
alert(main.defaultValue); // This will display 5678
main.defaultValue = "Hello World";
alert(main.defaultValue); // This will now display Hello World
};
This type of approach is covered in the following posts: -
How to span javascript namespace across multiple files?
JavaScript Module Pattern: In-Depth

Related

interacting with javascript through the chrome console [duplicate]

This question already has answers here:
Console access to Javascript variables local to the $(document).ready function
(8 answers)
Closed 6 years ago.
I'm using a shopping cart api to build an ecommerce website. The creators made an sdk and then you have to make your own .js file for some other functions.
While debugging I would insert a console.log(etc..) anywhere in my .js file so that I could debug object options and etc..
But I would like to be able to use the sdk as a live tool, so instead of having to edit my .js file with new console.log() lines, I'd rather just be able to type object.color_code and have the console output that string for the object color code. At the moment though it just gives me uncaught reference error, object is not defined.
I think this is because my custom .js file has all of it's script inside a $(function() { EVERYTHING }); SO, when I try to call anything in EVERYTHING from the console it says it's undefined, but if I just used console.log inside EVERYTHING it would work. So is there a way I can get around this?
Feel free to explain why it isn't working but I'd like a way to enable this, don't tell me there isn't a way, even if I have to prefix what I want with the .js file it's coming from each time, I don't mind
You were correct in that all of your variables inside the function are only being defined locally, and thus can't be accessed via the console. However, in Javascript there are at least two options for setting global variables from inside functions; If you use these to declare a variable you want to access from outside the function, it will work:
Assign a value to an undeclared variable: varname=value;
Assign the variable to the window object: window.varname=value; or window['varname']=value;
A possible workaround is to expose the object(s) that you want to debug in the global scope:
(function() {
var privateStuff = { foo: 'bar' };
// make privateStuff public for debugging purposes
window['debugObject'] = privateStuff;
})();
document.write(debugObject.foo);
If you want to expose several objects with rather common names that are likely to collide with existing ones, make sure to expose them within an object with an uncommon name rather than directly:
(function() {
var x = { str: 'this is' },
y = { str: 'a test' };
window['debugObject'] = {
x: x,
y: y
};
})();
document.write(debugObject.x.str + ' ' + debugObject.y.str);
If you're happy to change the source file then you could export whatever you want to access from EVERYTHING as a global.
$(function() {
//EVERYTHING
...
window.Ireply = window.Ireply || {};
window.Ireply.object = object;
...
});
console.log(Ireply.object); // some object
You can change a declaration like
$(function(){
var cart = {};
})
To
var cart;
$(function(){
cart = {}
})
Or
$(function(){
var cart = {};
window.cart = cart;
})
But you will want to avoid polluting global namespace. You will also want to be careful about using globals inside callbacks or loops where you can run into unexpected behaviors since local variables scope is often important to be kept local

js - avoiding namespace conflict

Thus far I've worked only with relatively small projects (and mostly alone), but this time I have to collaborate with other programmers... basically because of that I must plan the structure of the website very carefully for the avoidance of spending hours debugging the code.
At this point I suppose doing that in the following manner. I divide my code in modules and store each module in a separate file inside an object (or a function) with a made-up name (lzheA, lzheB, lzheC etc.) to avoid conflicts whether an object with the same name was used in an another piece of code. When the document is loaded, I declare a variable (an object) that I use as a main namespace of the application. Properties of the object are the modules I defined before.
// file BI.lib.js
var lzheA = {
foo: function() {
},
bar: function() {
},
}
// file BI.init.js
function lzheK() {
BI.loadPage();
}
// file BI.loadPage.js
function lzheC() {
var result = document.getElementById('result');
result.innerHTML = "that worked";
}
// and so on
var lzheA,lzheB,lzheD,lzheE,lzheF,lzheG,lzheH,lzheI,lzheJ;
// doing the following when the document is loaded
var BI = {
lib: lzheA,
menu: lzheB,
loadPage: lzheC,
customScripts: lzheD,
_index: lzheE,
_briefs: lzheF,
_shop: lzheG,
_cases: lzheH,
_blog: lzheI,
_contacts: lzheJ,
init: lzheK,
}
BI.init();
https://jsfiddle.net/vwc2og57/2/
The question... is this way of structuring worth living or did I miss something because of lack of experience? Would the made-up names of the modules confuse you regardless of the fact that each one used only twice - while declaring the variable and assigning it to a property?
I consider the namespaces a good option when you want to modularize applications in Javascript. But I declare them in a different way
var myModule = myModule || {}; // This will allow to use the module in other places, declaring more than one specificComponent in other js file for example
myModule.specificComponent = (function(){
// Private things
var myVar = {};
var init = function() {
// Code
};
return {
init: init // Public Stuff
};
})();
If you want to call the init method, you would call it like this
myModule.specificComponent.init();
With this approach, i guarantee that the module will not be overwritten by another declaration in another place, and also I can declare internal components into my namespaces.
Also, the trick of just exposing what you want inside the return block, will make your component safer and you will be encapsulating your code in a pretty way.
Hope it helps

Unexpected "double" namespace when using constructor function in submodule

I'm building my first real JS app (a tower defense game) and I've been struggling a little with my app structure. I've read about no littering the global namespace so I want to keep all my code in one single global variable while still being able to split my code in files (modules). I have managed to do this but I'm having doubts if I'm going the correct way with this.
The actual problem I'm having now is that when I create "entity" objects (through a constructor function which is actually a method of a submodule), the namespace is not app.entity.type_1 as I expected but app.entity.entity.type_1
/*
** file 1 (included first in html)
*/
var APP = (function (app) {
entity = app.entity || {};
entity.tracker = [];
app.init = function () {
entity.tracker.push(new app.entity.type_1(entity.tracker.length));
entity.tracker.push(new app.entity.type_2(entity.tracker.length));
console.log(entity.tracker[0]);
console.log(entity.tracker[1]);
};
return app;
})(APP || {});
/*
** file 2 (included after file 1 in html)
*/
APP.entity = (function (entity) {
entity.type_1 = function (id) {
this.type = "type 1";
this.id = id;
};
entity.type_2 = function (id) {
this.type = "type 2";
this.id = id;
};
return entity;
})(APP.entity || {});
APP.init();
Please check out the fiddle below.
http://jsfiddle.net/Percept/8stFC/13/
My question is, why does it repeat the "entity" namespace and how can I avoid this?
If you're referring to what Chrome thinks the class name is, that's just a best guess on its part. Since JavaScript has no first-class concept of namespaces, all the context it's really got is that the function that created it was assigned to a variable that was at the time called entity.type_1, and that that was within an IIFE whose result was assigned to APP.entity. Chrome thought the most helpful thing to do would be to concatenate those. You're not doing anything wrong, it's just that Chrome made a bad guess. For the record, Firefox just says [object Object].

Communication between scripts | Three methods

How do I properly communicate data betweens two scripts.
In this particular case I have an element in one script, but I want to append it in another script.
The simplest way I could do this is by using the global window object as go-between.
But globals are not best practice.
What is the correct way to pass this element to another script?
Both script are encapsulated in the module pattern.
Script 0 Create Element Point
var element = document.createElement( "div" );
element.innerHTML = response_text;
Script 1 Append Element Point
Vi.sta = {
// implemented in the boot loader - shared global space - appended child already - you don't have to append until now.
// Static data has already been composed.
// Pull off window and append or best practice
};
Both are encapsulated in the module pattern
(function(){
// the code here
})()
All JS scripts are run in the global scope. When the files are downloaded to the client, they are parsed in the global scope.
So if you've got
// File_1.js
var myObj = { colour : "blue" };
There's nothing stopping you from doing this:
// File_2.js
var otherObj = { colour : myObj.colour };
As long as File_1.js is loaded before File_2.js
If you are namespacing, ie: MYNAMESPACE = {}; and each file extends your namespace through modules (rather than "module pattern" referring to returning interfaces from immediately-invoking functions), then check for the module's existence.
If you ARE writing modules for a namespaced app, and you DO need access to variables from one module to another, then you should be providing an interface for that.
If you are SANDBOXING modules, then you need to provide them all a proxy similar to a service-locator or a "registry", or develop a messaging-system based on a mediator-pattern.
window.sharedSpace = {};
sharedSpace.sharedValue = 'foo bar';
That way you only have one global object instead of several.
Why don't you just pass the element to a function in the module?
var module1 = (function () {
return {
func1: function () {
// get your element
var someElement = ...;
// pass it to the other module
module2.func2(someElement);
}
};
}) ();
var module2 = (function () {
return {
func2: function (someElement) {
// do whatever you want with someElement
}
};
}) ();

How best to overwrite a Javascript object method

I'm using a framework that allows the include of JS files. At the top of my JS file I have something like:
<import resource="classpath:/templates/webscripts/org/mycompany/projects/library/utils.lib.js">
I want to override a fairly small method that is defined in the very large utils.lib.js file. Rather than make the change directly in utils.lib.js, a file that's part of the framework, I want to overwrite just one method. The utils.lib.js file has something that looks like:
var Evaluator =
{
/**
* Data evaluator
*/
getData: function Evaluator_getData(input)
{
var ans;
return ans;
},
...
}
I want to change just what the method getData does. Sorry for the basic question, but after importing the file which copies the JS contents into the top of my JS file, can I just do something like:
Evaluator.getData = function Mine_getData(input)
{
...
};
Yes, you can just reassign that method to your own function as you have proposed with:
Evaluator.getData = function Mine_getData(input)
{
...
};
This will successfully change what happens when the .getData(input) property is called.
Yes you can.
However Evaluator is not a proper 'class'. You can't write var x = new Evaluator();
So you are not overriding, but just changing the variable getData. That's why we say that in JavaScript, functions are first-class citizen, treated like any variable.

Categories