How to use Google API in a js file? - javascript

I want to use Google API inside a js file and how can I use it? I tried to use google.load() directly in the js file but was told that google is not defined. Then I tried to use the following code
var s = document.createElement('script');
but was told that document is not defined.
What should I do to use google api inside a js file? Thank you.
Here what I want to use is the Google Feed API.
The html code I used is
<!DOCTYPE HTML>
<html>
<head>
<title>
Example
</title>
<script src="https://www.google.com/jsapi" type="text/javascript"></script>
</head>
<body>
<div>
<p id="computation_results">please wait, computing … </p>
</div>
<script>
var worker = new Worker('numberworker.js');
worker.postMessage({first:123,second:456});
worker.onmessage = function (event)
{
alert(event.data);
document.getElementById('computation_results').textContent = event.data;
};
</script>
</body>
</html>
and the js file where I want to use the api is
// Our callback function, for when a feed is loaded.
function feedLoaded(result) {
if (!result.error) {
var container = document.getElementById("content");
container.innerHTML = '';
for (var i = 0; i < result.feed.entries.length; i++) {
var entry = result.feed.entries[i];
var div = document.createElement("div");
div.appendChild(document.createTextNode(entry.title));
container.appendChild(div);
}
}
}
function OnLoad() {
var feed = new google.feeds.Feed("http://www.digg.com/rss/index.xml");
feed.load(feedLoaded);
}
onmessage = function (event)
{
var fileref=document.createElement('script');
var filename="https://www.google.com/jsapi";
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", filename);
document.getElementsByTagName("head")[0].appendChild(fileref);
// google.load("feeds", "1");
// google.setOnLoadCallback(OnLoad);
var first=event.data.first;
var second=event.data.second;
postMessage("Work done! "+ " "+first+" "+second);
};

You need to include the API before you can use it. Try putting this in your head block:
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
To load the feed API, you can then have another script block like this:
<script type="text/javascript">
google.load("feeds", "1");
var feed = new google.feeds.Feed("<<url here>>");
...
</script>

I would check to make sure your html is validated first, or put up a link to a test file. Any slightest error can cause you to get any number of errors. I tried the following code in a file by itself, wrapped in tags, and was able to load the api. To load a javascript file using javascript you would use the following
var fileref=document.createElement('script');
var filename="https://www.google.com/jsapi";
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", filename);
document.getElementsByTagName("head")[0].appendChild(fileref);
Then after it you use the api calls
google.load(....)\
EDIT:
You are using html5 web workers, that use process outside of the browser, to create a script. This is not possible due to html5 workers do not have access to the DOM. http://www.sitepoint.com/javascript-threading-html5-web-workers/
You would have to create it outside of the worker or include in a script element

Related

Load another JavaScript file and acess var

I'm doing a work for school, and I'm doing a online plataforn to buy games online, I can just use HTML, CSS and JS so for each game e have a JS file with the informations, here is an example:
/*doom.js*/
var info = {
title : "doom",
price : "59.99",
off : "0%"
};
And my html page is that one:
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script src="games/functions.js"></script>
</head>
<body>
<label id="title"></label>
</body>
</html>
I have that page to all my games, so I use the GET method to know wich file I need to read. (game.html?id=doom)
I have this code to get the id chosed and load the file:
window.onload = function() {
id = getURLParameter('id');
loadGamefile("games/"+id+".js");
};
function getURLParameter(name) {
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search)||[,""])[1].replace(/\+/g, '%20'))||null;
}
function loadGamefile(filename){
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
fileref.setAttribute("src", filename)
    
    if (typeof fileref!="undefined")
document.getElementsByTagName("head")[0].appendChild(fileref);
loadinformation();
}
function loadinformation(){
document.getElementById("title").innerHTML = info.title; //info.title is from the doom.js file
}
The only problem is he dont change the label, but if I put a button on the btml code and onclick I say its the loadinformation() he load fine, but I want that automatic when the page loads and here is the error I get from console: functions.js:22 Uncaught ReferenceError: info is not defined, I think maybe is becouse the browser didn't had time to load the file, I don't know, can someone help me? Thanks and sorry for my english.
The problem is you aren't giving the browser a chance to parse your new script. You can give it a moment to do that using setTimeout.
function loadGamefile(filename) {
// your other code goes here
setTimeout(function() {
loadinformation();
}, 500); // wait half of a second
}
Ideally, you should have your data stored in a JSON file then load it using AJAX instead. There are numerous tutorials covering how to load JSON over AJAX.
As #Bergi pointed out, this solution is very fragile and relies on the script loading in under 500ms. Instead, you can listen for the load event to ensure you use the script as soon as it's ready.
function loadGamefile(filename) {
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
fileref.setAttribute("src", filename)
if (typeof fileref!="undefined")
document.getElementsByTagName("head")[0].appendChild(fileref);
// Wait for the script to load
fileref.onload = function() {
loadinformation();
};
}

"SpreadsheetApp is not defined" when accessing spreadsheet from JavaScript

I am receiving this error when trying to access a Google spreadsheet from JavaScript.
Uncaught ReferenceError: SpreadsheetApp is not defined
Why is this happening?
<html>
<head>
<script type='text/javascript' src='https://www.google.com/jsapi'></script>
<script type='text/javascript'>
function findAllBP() {
var sheet = SpreadsheetApp.getActiveSpreadsheet(); // error
var sid = SpreadsheetApp.openById('ID');
var dd = sid.getSheetByName('Published').getRange('A').getValues();
var name = sheet.getName();
console.log("name of spreadsheet" + name);
}
window.onload = function() {findAllBP();};
</script>
</head>
<body>
</body>
</html>
According to docs (https://developers.google.com/loader/) first you need to load a module and the use it's API:
google.load("search", "1");
But this is not an issue here. API that you are trying to use is a Apps Script API and it is not available on regular websites. It must be used in context of Spreadsheet.
Read more on Apps Script docs: https://developers.google.com/apps-script/

Load external file variable and at the same time avoid browser external file caching

I need to append timestamp to the javaScript file in tag url to avoid caching.
This function found here in stackoverflow seems to do it:
<script type="text/javascript">
(function(){
var randomh=Math.random();
var e = document.getElementsByTagName("script")[0];
var d = document.createElement("script");
d.src = "TESTINGX.JS?x="+randomh+"";
d.type = "text/javascript";
d.async = true;
d.defer = true;
e.parentNode.insertBefore(d,e);
})();
But the problem is that inside the file testingx.js I've placed the following code:
var hello = "Hello World!";
And for some reason the variable doesn't get the global scope (or maybe the problem is other).
My html is the following:
<!DOCTYPE html>
<HTML><HEAD>
<script type="text/javascript">
(function(){
var randomh=Math.random();
var e = document.getElementsByTagName("script")[0];
var d = document.createElement("script");
d.src = "TESTINGX.JS?x="+randomh+"";
d.type = "text/javascript";
d.async = true;
d.defer = true;
e.parentNode.insertBefore(d,e);
})();
</script>
</HEAD><BODY>
<h1>WiFi Mini Web Server</h1>
<script>
document.write(hello); //hello var is contained in the TESTINGX.JS file\n\
</script>
</BODY></HTML>
If you want the external script to block everything else until it loads but still need to load it from a dynamic URL (it sounds like you do), you should be able to document.write the script element directly instead of using the DOM methods.
<!DOCTYPE html>
<html><head>
<script>
var randomh = Math.random();
document.write('<script src="TESTINGX.JS?x=' + randomh + '"></' + 'script>');
</script>
</head><body>
<h1>WiFi Mini Web Server</h1>
<script>
document.write(hello); // hello var is contained in the TESTINGX.JS file
</script>
</body></html>
http://jsbin.com/ixagud/2/edit
You code for cache busting, also happens to ensure that the script is loaded in a "lazy", "non-blocking" manner. Which means the TESTING.js is loaded after your DOM is loaded. Which also means that the document.write script is run before the js file has loaded, and added the required var to the global scope.
There can be several solutions:
1. Remove defer and async from your loading script
Ensure variables from your script are accessed on your page, only after the script is actually loaded
Better yet, don't try to handle cache busting through clever javascript (I am assuming the html is question is served using some sort of server technology like a jsp or php script). Use the server technology to add a parameter with a random number or timestamp to the usual script tag in the html
Instead of using a script to bust cache, use a normal script tag, with a parameter that is same as the timestamp in millis, as on the day when you make the build, and embed in your microcontroller / server. Treat this like a version number of the js file. So clients can use the file cached in their browser, provided the version number is the latest.
This ant task http://code.google.com/p/ant-web-tasks/wiki/CacheBusting is a good way to implement point no 4. I have had good experience with it.
Hope this helps.
try this
<script type="text/javascript">
(function(){
var randomh=Math.random();
var e = document.getElementsByTagName("script")[0];
var d = document.createElement("script");
d.src = "TESTINGX.JS?x="+randomh+"";
d.type = "text/javascript";
d.async = true;
d.defer = true;
e.parentNode.insertBefore(d,e);
document.write(hello);
})();
</script>

Dynamic script hack callback

I have a page that only contains a string and need to read it from a page in a different domain. I have tried to do it via a dynamic script hack (to avoid the security restrictions) and can read that string but cant bring it in a callback to keep working with it in a variable.
My problem is that I need to do it only using javascript.
Here is the code that I am currently using:
index.html:
<html>
<head>
<script type="text/javascript">
function xss_ajax(url) {
var script_id = null;
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', url);
script.setAttribute('id', 'script_id');
script_id = document.getElementById('script_id');
if(script_id){
document.getElementsByTagName('head')[0].removeChild(script_id);
}
document.getElementsByTagName('head')[0].appendChild(script);
}
var url = "http://otherdomain.com/ping.html";
xss_ajax(url);
</script>
</head>
<body>
</body>
</html>
ping.html:
1|1739
Very much thanks and sorry my english.
Your result from ping.html dose not have any variables defined, if you say
made an object like
result = [1,1739];
and in index.html you declared
var result = [];
then you could work with that.

What's the simplest <script> tag with params

I want to include a script tag, while providing a parameter to it. This is what I came up with so far
Provide a parameter to script URL (cons: generate multiple JS files)
<script src="http://example.com/something.js?P=123" type="text/javascript"></script>
Hide parameter in script tag (cons: same as #1)
<script src="http://example.com/scripts/123/something.js" type="text/javascript"></script>
Google Analytics way (cons: ugly, complicated, global variables)
<script type="text/javascript" charset="utf-8">
var _something = _something || 123;
(function() {
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = 'http://example.com/something.js';
var ss = document.getElementsByTagName('script')[0];
ss.parentNode.insertBefore(s, ss);
})();
</script>
The best thing is to define things (functions &c) in the external script but execute nothing. Then have an inline script that calls functions/methods defined in the external script.
<script src="http://example.com/something.js" type="text/javascript"></script>
<script type="text/javascript">
something(123);
</script>
If the way the script is executed, depends on how it's called, you can add params like your option 1.
Other ways are:
<script params='{"abc": 123}' src="script.js"></script><!-- params is a non standard, non official attr that the script will read -->
or
<script>var _abc = 123;</script>
<script src="script.js"></script>
or even
<script src="script.js#abc=123"></script>
I have to agree with #outis though: load the same thing for everybody, always, and execute it like you/the client want(s) afterwards.
I do this for a cross-sub-domain XHR handler that I have. I call it as:
<script type="text/javascript" src="xd.js#subdomain"></script>
and then in the script, parse it as such (using jQuery):
$('script').each(function(){
if((src = this.src).indexOf('xd.js') < 0){ return; }
xds = src.substr(src.indexOf('#') + 1).split(',');
// do stuff with xds
});
Your first example does not need to generate multiple files. It can be used by JavaScript alone, by detecting window.location.href and parsing it (you might find the likes of http://phpjs.org/functions/parse_url:485 and http://phpjs.org/functions/parse_str:484 helpful in doing this: var queryString = parse_str(parse_url(window.location.href).query); ).
However, if you use something like #P=123 instead of ?P=123, you won't cause another download of the file by your users, so I'd recommend that instead (in which case change "query" in the above code sample to "fragment").
Another possibility is using the HTML5-reserved data-* attributes, and detecting their values within your script:
<script src="http://example.com/something.js" data-myOwnAttribute="someValue" data-anotherCustomAttribute="anotherValue"></script>
The script would then detect along these lines:
(function () {
function getScriptParam (attr) {
var scripts = document.getElementsByTagName('script'),
currentScript = scripts[scripts.length-1];
return currentScript.getAttribute('data-' + attr); // in future, could just use the HTML5 standard dataset attribute instead: currentScript.dataset[attr]
}
var myOwnAttribute = getScriptParam('myOwnAttribute');
// ... do stuff here ...
}());
The real advantage of Google's ugly API is that it allows developers to drop in that code in the <head> of the document (considered proper form), while still acting asynchronously in a cross-browser way. I think they could indeed avoid the global had they combined their dynamic script-tag technique with either of the above approaches.

Categories

Resources