I am trying to pass 4 variables from one js file to another.
I read here that you must write:
window.myVar = "foo";
to make your variable "super"-global.
In the first js file, I have
window.signJoueur1 = string1.charAt(7);
window.signJoueur2 = string2.charAt(7);
window.valeurJoueur1 = random1;
window.valeurJoueur2 = random2;
In the second js file, I did
console.log(window.signJoueur1);
console.log(window.signJoueur2);
console.log(window.valeurJoueur1);
console.log(window.valeurJoueur2);
function trouveCombinaison(signJoueur1, signJoueur2, valeurJoueur1, valeurJoueur2)
{
console.log(signJoueur1);
console.log(signJoueur2);
console.log(valeurJoueur1);
console.log(valeurJoueur2);
}
It should work, but all console.log return `undefined'.
If you want more informations here are the full codes:
first .js http://pastebin.com/0zJKFNem
second .js http://pastebin.com/TsWc7TxL
the html http://pastebin.com/t3SzwZSC
So, my question is, how can I actually pass through the variables?
You are trying to use the values before they exist.
The code that assigns the values to the variables are inside a function, and that function isn't called until you click a button. The code that tries to show the values is executed when the page loads, so it uses the variables before they have been assigned any values.
Actually i just had to put window. in the second console.log group.
Such as :
function trouveCombinaison()
{
console.log(window.signJoueur1);
console.log(window.signJoueur2);
console.log(window.valeurJoueur1);
console.log(window.valeurJoueur2);
}
The fact that the console.log out of the function don't work is that it's executed when the page loads, as explained by #Guffa.
Now it works.
Related
I am new to Javascript/backboneJS/RequireJS. In order to render my front end I have made one controller, one model and one view. Also, I have one dropdown in my html file.
So what I have done till now is in my html file at the END I have
require(['common'],function()
{
require(['jquery','fastclick','nprogress','charts','underscore','spinner'],function()
{
require(['firstDashboardController']);
});
});
So I am loading "firstDashboardController" and this controller loads all the modules accordingly and displays data in front end. So everything works fine.
Now I have a dropdown in the front end. When I select the dropdown, as per the id selected I want to retrieve the data. So I need to call "firstDashboardController" again so that everything gets rendered as per the new id that I have got.
So what am I suppose to do? Like do I need to UN-REQUIRE my "firstDashboardController" and then REQUIRE it again passing the new id. Because the controller is already loaded via Require beacuse I loaded it in my HTML file as mentioned above. But I need to load it again as per the new id selected it via dropdown. So how to go about it? Pleas help me. if any code snippet is required I can put that.
Code Snippet:
My Controller:
define(['backbone', 'firstSubViewModel','dropdownViewModel', 'dropdownModel'],
function(Backbone, firstSubViewModel, dropdownViewModel, dropdownModel) {
var ch = new dashboardModel.chart({});
if (localStorage.getItem('p_kt') && localStorage.getItem('p_acid') && localStorage.getItem('p_seid')) {
var data = {
tokenProp: localStorage.getItem('p_kt'),
accountIdProp: localStorage.getItem('p_acid'),
sessionIdProp: localStorage.getItem('p_seid')
};
$.when(
ch.fetch(data) // GETTING DATA FROM MODEL VIA AJAX CALL in my model.JS
).then(function() {
// Main Graph on Dashboard
new firstSubViewModel({
el: '#chartAnchor1',
model: ch
});
});});
I somehow need to call ch.fetch() again.
You aren't properly defining your controller. You currently have it as sort of a one-time setup method instead of something you can re-run later. Let's go step by step.
myLife.js:
define([], function() {
return "a complex series of failures";
});
By returning a value from define's callback, this defines that anytime I require "myLife", then it will provide "a complex series of failures" in the callback function. This is what Backbone and other AMD modules do to appear inside your code blocks. However, it only runs the contents once; and saves the result. So, this won't work:
incrementer.js:
var x = 0;
define([], function() {
x = x + 1;
return x;
});
(Trying to require incrementer would always give you "1".)
What you want to do is return a function - one you can re-run anytime.
incrementerV2.js:
define([], function() {
var x = 0;
return function() {
x = x + 1;
return x;
};
});
In any file, you can then have this:
require(['incrementerV2'], function(myIncr) {
myIncr(); // 1
myIncr(); // 2
});
...And, for the record, I would recommend having only one require statement in any given file whenever possible. You can add dependencies in that first-argument array if load order is important.
More commonly, people will have one module contain a self-defined object that has multiple functions in it, rather than the function I gave above. Returning and then using just one function is valid as well, depending on the use case. Any variable type works, but just remember it will always be the one and only same variable anytime you later need it.
Load Order
When the system retrieves myLife.js or incrementer.js above, there's an intermediate step before it actually runs the definition function we've defined. It will look at the first argument, the array of named dependencies, and figure out if there are still dependencies needed before it can run the function given. Example:
a.js: require(['b', 'c'], function(b, c) {
b.js: define(['c'], function(c) {
c.js: define([], function() {
a.js is requested first, but not run because it needs B and C. B loads next, but is ignored because C is not loaded. C runs, and then its return value is passed into A and B. This system is internally very smart, and should never request the same file twice or have conflicts if one file loads before another. You can use it much like imports in Java.
Also, let's say you only added 'c' in a.js so that b.js wouldn't crash, because it needs it loaded first - in that case, just take it out of A and it should work the same.
a.js: require(['b'], function(b) {
Just like A did, B will automatically load all its dependencies before it executes anything. A simple principle is to only refer a dependency if it's actually directly referenced in the file (or defines necessary global variables)
So as you might know, Razor Syntax in ASP.NET MVC does not work in external JavaScript files.
My current solution is to put the Razor Syntax in a a global variable and set the value of that variable from the mvc view that is making use of that .js file.
JavaScript file:
function myFunc() {
alert(myValue);
}
MVC View file:
<script language="text/javascript">
myValue = #myValueFromModel;
</script>
I want to know how I can pass myValue directly as a parameter to the function ? I prefer to have explicit calling with param than relying on globals, however I'm not so keen on javascript.
How would I implement this with javascript parameters? Thanks!
Just have your function accept an argument and use that in the alert (or wherever).
external.js
function myFunc(value) {
alert(value);
}
someview.cshtml
<script>
myFunc(#myValueFromModel);
</script>
One thing to keep in mind though, is that if myValueFromModel is a string then it is going to come through as myFunc(hello) so you need to wrap that in quotes so it becomes myFunc('hello') like this
myFunc('#(myValueFromModel)');
Note the extra () used with razor. This helps the engine distinguish where the break between the razor code is so nothing odd happens. It can be useful when there are nested ( or " around.
edit
If this is going to be done multiple times, then some changes may need to take place in the JavaScript end of things. Mainly that the shown example doesn't properly depict the scenario. It will need to be modified. You may want to use a simple structure like this.
jsFiddle Demo
external.js
var myFunc= new function(){
var func = this,
myFunc = function(){
alert(func.value);
};
myFunc.set = function(value){
func.value = value;
}
return myFunc;
};
someview.cshtml
<script>
myFunc.set('#(myValueFromModel)');
myFunc();//can be called repeatedly now
</script>
I often find that JavaScript in the browser is typically conceptually tied to a specific element. If that's the case for you, you may want to associate the value with that element in your Razor code, and then use JavaScript to extract that value and use it in some way.
For example:
<div class="my-class" data-func-arg="#myValueFromModel"></div>
Static JavaScript:
$(function() {
$('.my-class').click(function() {
var arg = $(this).data('func-arg');
myFunc(arg);
});
});
Do you want to execute your function immediately? Or want to call the funcion with the parameter?
You could add a wrapper function with no parameter and inside call your function with the global var as a parameter. And when you need to call myFunc() you call it trough myFuncWrapper();
function myFuncWrapper(){
myFunc(myValue);
}
function myFunc(myParam){
//function code here;
}
i am using Modernizr to load ressources to construct a jQuery layout.
The problem is that i cannot retrieve my $('body').layout() variable since it is inside one of the loaded resources (in script/webframe.js). I tried :
var myLayout;
function loadDefaultLayout() {
Modernizr.load([{
load: ['stylesheets/jquery.layout.css',
'script/jquery.layout.min.js',
'script/webframe.js'],
complete: function () {
myLayout = onDesktopWebFrameLoadComplete();
}
}]);
alert(myLayout.options.west.resizable);
}
Where onDesktopWebFrameLoadComplete is in script/webframe.js and returns the layout.
I tried moving alert(myLayout.options.west.resizable); just after onDesktopWebFrameLoadComplete and the alert was showing true. But when I move it out of the load() scope, I have an undefined error (for myLayout variable).
My question is :
I would like to know if it is possible to retrieve a variable outside of Modernizr.load() complete function scope.
My problem was only that I did not define my global variable in the right html file that called the function from the JavaScript file.
So in summary. Define your variable this way before everything else :
window.myLayout;
Then add your resource that will change your variable (that contains the load() function)
Change your variable in this resource : window.myLayout = "something-else";
You can now use it in the html file that included your resource.
I am just starting to get into JavaScript and couldn't find an exact scenario like this yet on SO, so I'm going to try my luck. I have two functions in an external JS file which create video feeds on our website:
function getVideos() {
//gets a list of videos
}
//callback function automatically called by getVideos()
function response(jsonData) { //can't change this line
var resp = document.getElementById("resp"); //can change this line and any subsequent lines
//parses data and populates resp
}
Then, from the HTML side, we just call getVideos() and the video feed will be created and populated.
However, I want to be able to pass any element ID I want into response() so that we can create multiple video feeds in different places on the same page. The thing is I can't change the function declaration of response() to include another parameter. Or at least I'm not led to believe I can by the company hosting our videos.
I've tried wrapping response() with getVideos() and passing an element ID from there, but then response() doesn't get called, and the only solution I can think of is resorting to storing an element ID in a global variable, which I know is a no-no in general in JavaScript.
My question is: Do I just bite the bullet and use a global variable, or is there another way?
For more info, here is our JS code as it stands now (with the closure): http://www.thebearrocks.com/Other/js/videoFeed/createVideoFeed.js
And here is the tutorial on response() we're following from the host of our videos: http://support.brightcove.com/en/video-cloud/docs/making-media-api-calls-dynamic-script-tags
may be you can use arguments? like so:
function response(jsonData) { //callback function automatically called by getVideos()
var elemId = arguments.length<2 ? "resp" : arguments[1]+"";
var resp = document.getElementById(elemId);
//parses data and populates resp
}
or, declare second argument what has default value like this:
function response(jsonData, elemId) {
elemId = elemId || "resp";
var resp = document.getElementById(elemId);
//parses data and populates resp
}
in this case function can be called as with one or two arguments
I've tried wrapping response() with getVideos() and passing an element ID from there, but then response() doesn't get called, and the only solution I can think of is resorting to storing an element ID in a global variable, which I know is a no-no in general in JavaScript.
My question is: Do I just bite the bullet and use a global variable, or is there another way?
No. Not the id variable needs to become global, but your local response function needs to for getting called back from the JSONP script - you're going to create a closure.
You can "export" it by calling
window.response = mylocalResponseFunction; // you did name that local var "response"
When I use code like this, it works fine:
function removeWarning() {
var systemStatus = document.getElementById("system-status");
systemStatus.innerHTML = "";
}
function indicateInvalidUsername() {
var systemStatus = document.getElementById("system-status");
systemStatus.innerHTML = "Invalid username";
}
However, when I then want to move the systemStatus to be a global variable, it doesn't work:
var systemStatus = document.getElementById("system-status");
function removeWarning() {
systemStatus.innerHTML = "";
}
function indicateInvalidUsername() {
systemStatus.innerHTML = "Invalid username";
}
What am I supposed to be doing here?
It really depends on where your JavaScript code is located.
The problem is probably caused by the DOM not being loaded when the line
var systemStatus = document.getElementById("system-status");
is executed. You could try calling this in an onload event, or ideally use a DOM ready type event from a JavaScript framework.
Make sure you declare the variable on "root" level, outside any code blocks.
You could also remove the var altogether, although that is not recommended and will throw a "strict" warning.
According to the documentation at MDC, you can set global variables using window.variablename.
My guess is that the system-status element is declared after the variable declaration is run. Thus, at the time the variable is declared, it is actually being set to null?
You should declare it only, then assign its value from an onLoad handler instead, because then you will be sure that it has properly initialized (loaded) the element in question.
You could also try putting the script at the bottom of the page (or at least somewhere after the system-status element is declared) but it's not guaranteed to always work.
Declare systemStatus in an outer scope and assign it in an onload handler.
systemStatus = null;
function onloadHandler(evt) {
systemStatus = document.getElementById("....");
}
Or if you don't want the onload handler, put your script tag at the bottom of your HTML.
A global variable would be best expressed in an external JavaScript file:
var system_status;
Make sure that this has not been used anywhere else. Then to access the variable on your page, just reference it as such. Say, for example, you wanted to fill in the results on a textbox,
document.getElementById("textbox1").value = system_status;
To ensure that the object exists, use the document ready feature of jQuery.
Example:
$(function() {
$("#textbox1")[0].value = system_status;
});
To define a global variable which is based off a DOM element a few things must be checked. First, if the code is in the <head> section, then the DOM will not loaded on execution. In this case, an event handler must be placed in order to set the variable after the DOM has been loaded, like this:
var systemStatus;
window.onload = function(){ systemStatus = document.getElementById("system_status"); };
However, if this script is inline in the page as the DOM loads, then it can be done as long as the DOM element in question has loaded above where the script is located. This is because javascript executes synchronously. This would be valid:
<div id="system_status"></div>
<script type="text/javascript">
var systemStatus = document.getElementById("system_status");
</script>
As a result of the latter example, most pages which run scripts in the body save them until the very end of the document. This will allow the page to load, and then the javascript to execute which in most cases causes a visually faster rendering of the DOM.