JavaScript: Accessing Variables Defined in External .js Files [duplicate] - javascript

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Dynamically Importing JavasScript
Is there a way to access variables which come from external imported JavaScript .js files?
In the external .js file I define a varialbe such as follows:
// JavaScript Document
var PETNAME = "Beauty";
After dynamically importing that code, I wish to access PETNAME variable, but I do not get the defined value:
alert("Pet Name: " + PETNAME);
What can be wrong, and is there a way to bring values from external .js code into the master JavaScript?
Thank you.

To import JS dynamically, you need to consider onreadystatechange and load events which are run when the script is parsed by the browser and available to you. You can use this function:
function getScript(url, callback) {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
script.onreadystatechange = callback;
script.onload = callback;
document.getElementsByTagName('head')[0].appendChild(script);
}
And you can use it like this:
getScript('path to your js file', function(){
alert("Pet Name: " + PETNAME);
});

Make sure you are including external file before trying to access variable defined in it. Also make sure the variable in the external file is not defined inside function, in which case they range is limited to that function only. If this not helps try removing keyword var before variable, this will create global variable.

Related

JavaScript insert script with async and use functions from it? [duplicate]

This question already has answers here:
Accessing variables after dynamically loading a script
(2 answers)
Closed 8 years ago.
I have written a small widget which I include onto pages like this:
<script type="text/javascript">
var _sid = '1';
(function() {
var se = document.createElement('script'); se.type = 'text/javascript'; se.async = true;
se.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://') + 'dev.domain.com/widget/hello.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(se, s);
})();
</script>
Now I want to find a way to call functions that exist within hello.js, which currently looks like this:
var widget = function () {
function setName(a) {
console.log(a);
}
return widget;
}();
So I want to be able to make a call to setName like so: widget.setName("Andy")
...from the embed page, but for some reason I get "widget is undefined."
Any ideas what I am doing wrong?
Before you use widget, you need to know it is loaded, there are multiple options for that:
Use requireJs or something like it.
Implement a callback function in the javascript you are loading, say it will fire 'document.onHelloIsLoaded', then if you want to know if hello is loaded, just set that variable to a function.
Make a loop, checking if the widget variable is set. setInterval (which cancels itself when widget is found and the code has executed)
you also need to make the setName variable accessible when you have access to widget, which it now isn't. You should put something like this:
var widget = {};
widget.setName = function()...
return widget;

Javascript: usage of require in Appcelerator Titanium

I am quite new to javascript and I am struggling with a simple problem. I have to split up codes into separate files. As an example I have a file called Database.js. In that file I have the following lines:
function Database(){
//someStuff
this.fetchAll = function(){
//some stuff
return something;
}
}
Now I want to use the Database.js code in the file app.js. So I write the following code in app.js:
var Database = require('Database');
var myDB = new Database();
var result = myDB.fetchAll();
However, I get the error Script Error = '[object Database]' is not a constructor (evaluating 'new Database()') at app.js (line 3).
What is my mistake?
Before you moving to the development, you need to understand thoroughly about CommonJS Modules in Titanium. Then it will be more simple for you. Also refer the require function
Let's come to your error. [ERROR] [object Database]' is not a constructor (evaluating 'new Database()') at app.js (line 3) means that the module you created is not constructor. Your constructor function might not return any value. Read simple usage of CommonJS module. I'm sure it will resolve your issue.
There is an alternative way, you can include your Database.js file in your app.js. You does not need to return anything and no need to use require function. You just need to use the include method. Just write Ti.include('Database.js'); inside your app.js and you can access all the global variables and functions inside the Database.js file
This question is old but it has not been answered yet. So i will just provide the answer for anyone who is visiting here.
You have to export you function as global. To do so you would declare it as below
exports.fetchAll = function Database(){
//some stuff
return something;
};
You can also declare the function so that it can be used globally as well as locally within the file
var fetchAll = function Database(){
//some stuff
return something;
};
exports.fetchAll = fetchAll;
Then assuming the file name is Database and it is in same folder as app.js, you can use it as below
var Database = require('Database');
var result = Database.fetchAll();
edit: This answer is javascript general and it's not oriented towards Appacelerator Titanium.
There is no such include or require in javascript. You can on the other hand do one of the following
Include a script tag before your script to include Database.js
<script type="text/javascript" src="Database.js" >
OR
Add it dynamically
function loadScript(url, callback)
{
// adding the script tag to the head as suggested before
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// then bind the event to the callback function
// there are several events for cross browser compatibility
script.onreadystatechange = callback;
script.onload = callback;
// fire the loading
head.appendChild(script);
}
The problem seemed to be the usage of the variable name 'Database'. Maybe there is somewhere a name collusion.
I am sorry that I did not know that the usage of require is not a basic concept of js.
Just a quick guess here. If you use CommonJS then you have to tell what should be available outside of the module. The way you lay out that you have made the Database "object" you would need to add:
module.exports = Database;
somewhere in your module. I always put them at the end - but not sure that is a requirement.
You can also make individual functions available outside of a module by specifying:
exports.getMyDatabase = getMyDatabase;
Where "getMyDatabase" is a function you have specified in the module. I use this way to "hide" certain implementation details of some functions from the outside and just make available the functions I want the developer to be able to call ;-)
/John
I think this is the right usage of require js:
require(["Database"], function() {
var myDB = new Database();
var result = myDB.fetchAll();
});
http://requirejs.org/docs/jquery.html

Check if javascript is already attached to a page?

Is there any way to check if javascript file is already attached to the page by its file name.
For eg :
if ("path-to-script/scriptname.js") already embeded
{
call related function
}
else
{
Append '<script src="path-to-script/scriptname.js" type="text/javascript"> </script> '
call related function
}
Basically I dont want 1 script to be attached twice on the same page.
You might not always know what objects or functions a script contains in advance, in such cases you can search for script tags containing the desired src.
With jquery:
$("script[src*='"+scriptName+"']");
Without jquery:
document.querySelector("script[src*='"+scriptName+"']");
You'd need to test whether the actual function from the script file exists, like this:
if (window.function_name) {
// script loaded
} else {
// script not loaded
}
I agree with #zathrus though I think you should be using requirejs for things like this. The idea is that dependencies must be fetched before executing the code. The above method you are using may work but you can not guarantee anything.
RequireJS will beautifully maintain all the dependency loading. It is very easy to learn as well.
Simply check if the library is defined, otherwise import it:
if ( !jQuery ) {
var s = document.createElement('script');
s.type = 'text/javascript';
document.body.appendChild(s);
s.src = "path-to-script/scriptname.js";
void(0);
}
// call function
you really need a script loader.. because as you said you want it specific with the javascript resource filename and this is sort of your javascript files are depending to each other
www.headjs.com
www.modernizr.com
www.yepnopejs.com
I thought this will help you.
if (typeof scriptname== "undefined") {
var e = document.createElement("script");
e.src = "scriptname.js";
e.type = "text/javascript";
document.getElementsByTagName("head")[0].appendChild(e);
}

Reference External JavaScript File in Function

Is it possible to reference a JavaScript file inside of a JavaScript function?
Therefore i am wanting to convert this:
<script type="text/javascript" src="http://crypto-js.googlecode.com/files/2.5.3-crypto-sha1-hmac.js"></script>
<script type="text/javascript">
var hmacString = Crypto.HMAC(Crypto.SHA1, "Message", "Secret Passphrase", { asString: true });
</script>
In to:
function hmac (input){
var hmacString = Crypto.HMAC(Crypto.SHA1, "Message", "KEY", { asString: true });
return hmacString;
}
I am using a tool called Cast Iron, which therefore restricts JavaScript down to only a function, but i need to call an external file, to load the needed functionality.
Is this even possible?
If I understand correctly, yes you can access functions and classes from one JS file as long as the other class was loaded before you attempt to access it.
So, if some-javascript-file.js has a function named getThings(), then you can do this:
<script type="text/javascript" src="http://cdn.example.com/js/some-javascript-file.js"></script>
<script type="text/javascript">
var things = getThings(); // getThings is a publicly accessible function in an external class.
</script>
Yes, you can load other js files with javascript. Depending on the load state where your function is executed, you may either use
document.write('<script type="text/javascript" src="http://crypto-js.googlecode.com/files/2.5.3-crypto-sha1-hmac.js"'+'><'+'/script>"');
// loads synchronouly and executes
Crypto.HMAC(...); // is available here
Watch out that document.write breaks the whole page once your DOM is loaded. You can also use:
var s = document.createElement("script");
s.type = "text/javascript";
s.src = "http://crypto-js.googlecode.com/files/2.5.3-crypto-sha1-hmac.js";
s.onload = function() {
// the file should be executed now so
Crypto.HMAC(...); // is available here
};
document.head.appendChild(s); // load asychronously
See also Load js from external site on fly
OK the screenshot kind of helps. It seems you want something from an external JS file, and to manipulate it inside this function.
So you could have one javascript file with:
var foo = 'foo'; //this is in the global scope
and then your other file has:
function hmac(key){
alert(document.foo);
}
should access what you want

Can't access variables from dynamically loaded javascript

I'm using a fairly simple system to load javascript dynamically:
include = function (url) {
var e = document.createElement("script");
e.src = url;
e.type="text/javascript";
document.getElementsByTagName("head")[0].appendChild(e);
};
Let's say I have a file test.js which has the following contents:
var foo = 4;
Now, in my original script, I want to use
include(test.js);
console.log(foo);
However, I get a 'foo has not been defined' error on this. I'm guessing it has to do with the dynamic script being included as the last child of the <head> tag. How can I get this to work?
It is because you have to wait for the script to load. It is not synchronous like you would think. This may work for you:
include = function (url, fn) {
var e = document.createElement("script");
e.onload = fn;
e.src = url;
e.async=true;
document.getElementsByTagName("head")[0].appendChild(e);
};
include("test.js",function(){
console.log(foo);
});
That is one problem, but it also takes time for the browser to download and parse the remote JS file — and it hasn't done that before you call console.log.
You need to delay things until the script has loaded.
This is easiest done by letting a library do the heavy lifting, jQuery has a getScript method that lets you pass a callback to run when the script has loaded.

Categories