Call variable from another script in HTML - javascript

I currently have a HTML file that has one script that is declared as follows:
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
code.......
var a = "hello"
});
</script>
I am trying to add another script within the HTML file that will call on this variable "a". Right now, I am doing something like this:
<script type="text/javascript">
alert(a);
</script>
But it is not alerting anything. If I replace a with a string like "hello", I do get alerted. Am I calling the variable wrong? I've tried searching for solutions but all of them say you should be able to easily call variables from another script assuming that script is declared and initialized before. Thanks.

Move the a declaration outside of the function.
E.g.,
var a;
$(document).ready(function() {
code.......
a = "hello"
});
And then later on...
alert(a);
Remember that variables are function-scoped, so if you define it inside of a function, it won't be visible outside of the function.
Update based on comments:
Because you now have a timing issue when trying to interact with the a variable, I would recommend introducing an event-bus (or some other mechanism) to coordinate on timing. Given that you're already using jQuery, you can create a simple bus as follows:
var bus = $({});
bus.on('some-event', function() {});
bus.trigger('some-event', ...);
This actually lends itself to some better code organization, too, since now you really only need the bus to be global, and you can pass data around in events, rather than a bunch of other random variables.
E.g.,
var bus = $({});
$(document).ready(function() {
var a = 'hello';
bus.trigger('some-event', { a: a });
});
And then in your other file:
bus.on('some-event', function(e, data) {
alert(data.a);
});
JSBin example (obviously not spread across multiple files, but the same principles apply).

Replace your code as
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script type="text/javascript">
var a="";
$(document).ready(function() {
a = "hello";
});
</script>
Now you can access the variable a as below.
<script type="text/javascript">
alert(a);
</script>
The problem with your code was that, you was declaring the variable a inside $(document).ready() which made it local to the ready().

When you write a inside function block you make it a local variable, you can move variable declaration outside of the function block as other answer say or you can use:
$(document).ready(function() {
window.a = "hello";
});
and later:
alert(a);
In both cases you are declaring a as a global variable and that is not recommended.

Related

MVC - Construct javascript object in my index that will be available in my script file

I want to initialize in my index javascript object with urls as properties, I need to initialize it on my view because of the #Url.Action that available in my view. so it will look like this:
Index.cshtml:
window.onload = function () {
myUrls=new Object();
myUrls.url1='#Url.Action("MyAction1","MyControllerName")';
myUrls.url2='#Url.Action("MyAction2","MyControllerName")';
myUrls.url3='#Url.Action("MyAction3","MyControllerName")';
myUrls.url4='#Url.Action("MyAction4","MyControllerName")';
}
Now I have script in my Script folder and I want to access these urls in my script.
How can I achieve this? Can I initialize this object somehow in my script instead of my view?
Because you've done this inside a function, the myUrls variable is scoped to that function. Once the function ends, myUrls goes out of scope and is no longer available. To make it stay around, you have to make it global by either taking it out of the window.onload (which doesn't make any sense anyways for a static variable declaration), or simply declare the variable first in the global namespace.
<script>
var myUrls;
window.onload = function () { ... }
</script>
But again, like I said, you don't need the window.onload because you don't have to wait for the DOM to be ready to declare a variable. So just do:
<script>
var myUrls = {
url1: ...,
url2: ...,
...
}
</script>
You don't need to create a new object explicitly, just use the object notation { ... }.
Finally, since you're adding this to the global namespace, I seriously recommend that you create your own namespace:
<script>
var MyAwesomeAndUniqueNamespace = MyAwesomeAndUniqueNamespace || {};
MyAwesomeAndUniqueNamespace.myUrls = {
...
}
</script>

Pass variable value from one javascript to another

I have created Master Page EXAMPLE1.Master for my .net web application. Their I am storing value in JavaScript variable. I want to retrieve that variable in another JS File.
EXAMPLE1.Master:-
<script language="javascript" type="text/javascript">
$(document).ready(function() {
var pageAccess = '<%=Session["UserAccess"]%>';
masterPageLoad();
});
</script>
<script language="javascript" type="text/javascript" src="JS/pageActions.js">
</script>
pageAction.js
//Retrieve pageAccess variable here.
Definition of masterPageLoad(); is present in pageAction.js file
declare your pageAccess variable, before $(document).ready(function() {
like
var pageAccess = '<%=Session["UserAccess"]%>';
$(document).ready(function() {
masterPageLoad();
});
Move your variable declaration outside the function
var pageAccess = '<%=Session["UserAccess"]%>';
$(document).ready(function() {
masterPageLoad();
});
This variable should now be visible in any JS file.
It would be preferable if you could do something like this:
$(document).ready(function() {
masterPageLoad('<%=Session["UserAccess"]%>');
});
And then update your pageActions.js accordingly:
function masterPageLoad(pageAccess) {
...
}
But if you need to work with an external variable, the reason it's currently not working is that it's defined within the scope of the DOMReady handler. You should either extract the variable declaration to be outside of the DOMReady handler, or you should create a global variable:
window.pageAccess = '<%=Session["UserAccess"]%>';

Help with Javascript scope

This example is a simplified version of my code. I'm still trying to grasp the new way of writing javascript (as opposed to the way 10 years ago) so thanks for your patience. I need globalVal's value to be accessible and I'm having trouble. The value is obtained from a function that is called as an argument from another method. The example is probably easier to see. Just need to be able to have access to globalvar from everywhere in the DOM. Is this possible? Thanks
<html>
<head>
<script type="text/javascript">
var globalvar;
function initialize() {
var someVariable = 5;
doSomething(someVariable, getTheVar);
}
function doSomething(someVariable, expectGlobalVar) {
//alert(someVariable);
alert(expectGlobalVar);
}
function getTheVar() {
globalVar = "test";
return globalVar;
}
</script>
<title></title>
</head>
<body onload="initialize()">
This is a test
</body>
</html>
You're mostly fine, you can directly access globalVar from any script running anywhere in the page if you declare it the way you have.
Specifically: Using var x; at page-level scope (that is, outside of any function) declares a property on the window object (it has a special feature in that it can't be deleted, but that's not important here).
var foo = 2;
window.foo = 2; // Basically the same other than the delete thing we're not worrying about here
And so:
var foo = 2;
alert(foo); // alerts "2"
alert(window.foo); // also alerts "2"
window.bar = 4;
alert(window.bar); // alerts "4"
alert(bar); // also alerts "4"
Naturally this is only true at the top level, outside of any functions. Inside functions, you're declaring something local to the function. (In essence; it's actually a lot more interesting than that.)
But since you've asked about scope, it's worth nothing that all of the other things you've defined (initialize, getTheVar, doSomething) are also globals. In general, you want to avoid putting anything in the global namespace that you can avoid putting there.
For that reason, I advocate always using a "scoping function":
(function() {
// your code here
})();
...and explicitly exporting exactly and only the things you really need to be global (by assigning them to properties on window).
In your case, you've said you need globalVar and you've also used initialize (although there are other ways to do what you're doing in initialize), so you could do this:
(function() {
var globalvar;
// Exports
window.globalVar = globalVar;
window.initialize = initialize;
// Implementation
function initialize() {
var someVariable = 5;
doSomething(someVariable, getTheVar);
}
function doSomething(someVariable, expectGlobalVar) {
//alert(someVariable);
alert(expectGlobalVar);
}
function getTheVar() {
globalVar = "test";
return globalVar;
}
})();
But you can take it further. Since you're not calling initialize until the load event of the body element, you could avoid publishing initialize. Just put your script tag at the end of the document, just before the closing </body> tag (as the YUI folks recommend), and do your initialization there:
<html>
<head>
<title>...</title>
</head>
<body>This is a test
<script type='text/javascript'>
(function() {
var globalvar;
// Initialization
initialize();
// Exports
window.globalVar = globalVar;
// Implementation
function initialize() {
var someVariable = 5;
doSomething(someVariable, getTheVar);
}
function doSomething(someVariable, expectGlobalVar) {
//alert(someVariable);
alert(expectGlobalVar);
}
function getTheVar() {
globalVar = "test";
return globalVar;
}
})();
</script>
</body>
</html>
The DOM is fully loaded and ready to go at that point.
But we can go even further if we want: We can have nothing in the global namespace if we like. If you hook up all of your handlers within your initialize function rather than using onload, onclick, and similar attributes, there's no need for globalVar to be global except to your code. (You hook up handlers after the fact by using attachEvent [on IE], addEventListener [on standards-based browsers], or better yet using a library like jQuery, Closure, Prototype, YUI, or any of several others.)
You should call function getTheVar instead of passing it:
function initialize() {
var someVariable = 5;
doSomething(someVariable, getTheVar());
}
You're doing it right.
Any variable which is declared in global scope, just like you have in the example, will be available from every scope in the window.
(BTW, declaring a global var is [almost] equivalent to window.myVar = someValue;)
The problem in your example is that you are not actually calling getTheVar on the fourth line, but rather just passing the function itself. You probably want this:
doSomething(someVariable, getTheVar());

Javascript namespace init when called from jquery.ready()

Is the following method wrong way of declaring namespace in Javascript? It is from the book I'm reading and doesn't seem to work in my code.
<script type="text/javascript">
var mynamespace = {};
if(Drupal.jsEnabled){
$(document).ready(mynamespace.init);
}
mynamespace.init = function() {
$("#mybutton").bind("click",function(){
alert('hello');
});
}
</script>
It looks like your code is dependent on jQuery. Make sure that is loaded before you run this script. Also, define your function before it gets called. Try this:
var mynamespace = {};
mynamespace.init = function() {
$("#mybutton").bind("click",function(){
alert('hello');
});
}
if(Drupal.jsEnabled){
$(document).ready(mynamespace.init);
}
What seems to be going wrong here is that the mynamespace.init function isn't defined at the time you are hooking it up to $(document).ready.
This should work as expected:
<script type="text/javascript">
var mynamespace = {};
mynamespace.init = function() {
$("#mybutton").bind("click",function(){
alert('hello');
});
}
if(Drupal.jsEnabled){
$(document).ready(mynamespace.init);
}
</script>
You may also consider forming it like this, as it is easier to understand (at least to me anyhow)
<script type="text/javascript">
var mynamespace = {
init : function() {
$("#mybutton").bind("click",function(){
alert('hello');
})
};
if(Drupal.jsEnabled){
$(document).ready(mynamespace.init);
}
</script>
Be careful using $(document).ready(mynamespace.init);. When executed in this way, this is no longer a reference to mynamespace, normally it would be equal to window, but jQuery do some call magic in the background to set it equal to document. It won't hurt you in this instance, but be wary of it in the future.
$(document).ready(function () {
mynamespace.init();
});
Is how I would do it.
In this case, the reason your code isn't working is that the init method of mynamespace isn't defined at the document $(document).ready(mynamespace.init) is called.
What strikes me as odd, at least working mostly in C#, is that a namespace should not directly contain code logic. In C# it can't, that is what classes are for. So for me, having an init function on a namespace is a contradiction.
Yes, you can use object as a namespace. Another way to form a namespace is to use closures:
(function(inner_variable_1, inner_variable_2) {
// define whatever here, they won't pollute namespace outside this closure
})(outer_variable_1, outer_variable_2);
Popular example is jQuery's noconflict-mode, which enables you to use $ variable in your jQuery code without making $ a global variable, thus leaving the global $ for another use.

Problem accessing global javascript variables

My application has something like the following structure
window.object1;
window.object2;
$(document).ready(function() {
window.object1 = new type1object();
});
function type1object() {
//lots of code
this.property = 'property';
window.object2 = new type2object();
}
function type2object() {
//lots of code
this.property = new type3object();
}
function type3object() {
//lots of code
console.log(window.object1);
this.property = window.object1.property;
}
The problem is that whenever I try to access window.object1 from anywhere other than the document ready callback it comes back as undefined, this is even though when I inspect the DOM window.object1 is defined exactly as I expect it to be.
I've tried doing the same as above but using simple global variables instead (i.e. var object1 instead of window.object1) ... Tried declaring initial dummy values for object1 and object2 in various places... but run up against the same problem.
Does anyone know why I can't access my global variables globally?
You have to make sure you are evaluating window.object1 after initiating it.
That is, in your case, only after document.ready finished executing
If you look at this example below you can see that at click both are initialized.
<html>
<body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script>
$(document).ready(function() {
window.object1 = new type1object();
window.object2 = new type2object();
//console.log(window.object1);
});
$(document).click(function(){
console.log(window.object1);
console.log(window.object2);
});
function type1object() {
}
function type2object() {
}
</script>
Since you are not setting the value of window.object1 until you are inside the document ready function, you wont be able to access it until it has run.
Nothing in your code shows that you couldn't just remove that document ready call altogether. It is generally reserved for waiting for elements to load in the dom, which it doesn't seem like you are doing. If you somehow do have elements that need to be waited on inside of code that isn't there, just put your script at the bottom of the page, right above the tag. This will do the equivalent of document ready.
writing the code really stripped out made the answer fall out - I was creating something that referenced object1 during the construction of object1.
So I changed it to this, so that the object exists (though with no content) before anything tries to reference it:
window.object1;
window.object2;
$(document).ready(function() {
window.object1 = new type1object();
window.object1.construct();
});
function type1object() {
//lots of code
this.construct = function() {
this.property = 'property';
window.object2 = new type2object();
};
}
function type2object() {
//lots of code
this.property = new type3object();
}
function type3object() {
//lots of code
console.log(window.object1);
this.property = window.object1.property;
}

Categories