javascript load other script - call function - undefined - javascript

I have this JS:
<script type="text/javascript">
var aaascript = document.createElement('script'); aaascript.type = 'text/javascript';
aaascript.src = ('https:' == document.location.protocol ? 'https://xxx' : 'http://xxx') + '/aaa.js';
var aaas = document.getElementsByTagName('script')[0]; aaas.parentNode.insertBefore(aaascript,aaas);
callthis('somevalue');
</script>
this code generates a script tag and inserts it to the page. in the script aaa.js is the function callthis. but when I call the function there is this error:
Uncaught ReferenceError: callthis is not defined (anonymous function)
what goes wrong here?

The script tag is being created but the script is then loaded from the server. callthis() is being called in between these two events; that is, before the script is fully loaded, and so the method doesn't exist.
Use the .onload event of the script tag to delay calling callthis() until the script is fully loaded, as documented here.

Related

Javascript Google Custom search engine

Issue - Error
I get this error,
Error: CSE.js:130 Uncaught ReferenceError: google is not defined
Issue - Description
However, if I use the chrome console in web tools, if google.search.... is used, it works.
not sure why google isn't loading in the context of my code, please help.
Code
// Generate CSE Script
let scr = document.createElement('script'),
head = document.head || document.getElementsByTagName('head')[0];
scr.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//www.google.com/cse/cse.js?cx=' + cse_cx;
scr.async = false; // optionally
head.insertBefore(scr, head.firstChild);
// Get Results Element
let element = google.search.cse.element.getElement('searchresults-only0');
after code executes, etc.
doing this will work
You might want to use the Search Element initialization callback in this case. Check out https://developers.google.com/custom-search/docs/element#init-callback
So adding a "Delay" works,
I wrapped my code with a setTimeout(function(){ /*CODE HERE*/ }, 1000); after dynamically injecting the script.

Load jQuery Only If Not Present without document.write

is there any way to load jQuery file if it's not present without using document.write
<script>
window.jQuery || document.write('<script src="/path/to/your/jquery"><\/script>');
</script>
this way is good but it has major issue because if the visitor has slow connection the browser will prevent it from executing
when it happen I get this warning
file is invoked via document.write. The network request for this script MAY
be blocked by the browser in this or a future page load due to poor
network connectivity
I tried many solutions but nothing worked
You can pass a load callback to the IFFE that will be executed when the script loads or invoked immediately if jQuery exists.
var load = function(){
// your jQuery code goes here
$('#hello').html('jQuery Loaded');
};
(function(window, loadCallback){
if(!window.jQuery){
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://code.jquery.com/jquery-3.3.1.min.js";
script.onload = loadCallback;
document.head.appendChild(script);
}else{
loadCallback();
}
})(window, load);
<div id="hello"></div>

Google WebSearch API custom search throws TypeErrors

We have a custom searchbar on our website and I noticed that sometimes (9/10 times) the JS will throw this error, which forces the content that you searched for to not render
www.googleapis.com/customsearch/v1element?key=AIzaSyCVAXiUzRYsML1Pv6RwSG1gu…oogle.com&callback=google.search.Search.apiary####&nocache=1446053383742:2
Uncaught TypeError: google.search.Search.apiary#### is not a function
Search page when error is thrown:
Search page with error truncated/resolved
But if I were to refresh, or research, this error is trumped and will render all of my searches. After looking through the file, I found out the google.search.Search.apiary#### that they are referring to is only mentioned once. So I believe that this error is truncating the entire file when it does show up. What could be causing this, what would be some options for fixing it?
Alright, I stumbled upon an answer:-
After doing some more research, I found that this user on Google Forums also has the same issue.
To put it simply, the way it works is you use a <script> to generate your searchbar.
You have this function + html element for your search bar
<script>
(function() {
var cx = '###';
var gcse = document.createElement('script');
gcse.type = 'text/javascript';
gcse.async = true;
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
'//cse.google.com/cse.js?cx=' + cx;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(gcse, s);
})();
</script>
<gcse:searchbox-only resultsUrl="/search-results"></gcse:searchbox-only>
So we generated the bar in our <div class="header"> which is a HAML element, as a part of a template. So it was always loaded within every header. Since we have 10 pages, this same script was generated 1 time per page.
Our Google CSE is made to search and then redirect to the url /search-results where it generates the results.
To generate the results, you needed this function and HTML
<script>
(function() {
var cx = '###';
var gcse = document.createElement('script');
gcse.type = 'text/javascript';
gcse.async = true;
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
'//cse.google.com/cse.js?cx=' + cx;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(gcse, s);
})();
</script>
Which is the same as the one being loaded in our Header.
With this set up, the results page would call that <script> twice when loading in, and cause the JS to break. So after removing the <script> loading the results, it stopped throwing the error.
To put it brief, just make sure you aren't calling the same function twice on your results page, and it should clear up the Uncaught TypeError.
Don't. Repeat. Yourself
--ether
In my case I accidentally had the form and script for the Google Custom Search repeated twice on the same page. Once the second lot was removed it stopped giving the error.

JavaScript dynamic loading

I have senerio, where I need to render my HTML page by using dynamic JavaScript.
I am using loadScript function to load external JavaScript and passing callback funtion. In my HTML page , I am loading this script for my header.
My header section is working perfectly after the script is loaded and I my head section I can see my new script.
However , when I am trying to use the variables from this script its undefined.
function loadScript(url,callback){
var script = document.createElement("script");
script.type = "text/javascript";
script.id="acvDataRequest";
document.getElementsByTagName("head")[0].appendChild(script);
if (script.readyState){ //IE
script.onreadystatechange = function(){
if (script.readyState == "loaded" ||
script.readyState == "complete"){
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function(){
alert(dataHeader) // I CAN SEE MY OBJECT FROM LOADED SCRIPT
callback();
};
}
script.src = url;
alert(dataHeader); // IT SAYS UNDEFINED
}
calling a script using :
var actionName ="JSONdata/json.js";
loadScript(actionName,mergeTemplateJSONScript);
Please advice , why i can't see my variables even if my script is there.
Inside script.onload , I am able to see my variable but not outside
The line script.src = url; triggers the loading of the script file. If you call alert immediately after it your external script has not been loaded yet. You can only access variables from the json once the onreadystatechange or onload functions have been called.
What you should do is using it like this:
var actionName ="JSONdata/json.js";
loadScript(actionName,function(){
alert(dataHeader);
});
What you assign:
script.src = url;
that just starts the loading of the dynamic script. When you call the second alert() on the very next line your script has not yet loaded (it is loading in the background at that point). You can only reliably access the variables from the newly loaded script from within the onload handler or in some function called from the onload handler.
Keep in mind that the dynamic loading of scripts is asynchronous. That means it happens in the background while other scripts keep running (thus your second alert() runs before the script has finished). And, then the script finishes loading some time later and when it does the onload handler is called.
So, when you dynamically load scripts, all code that uses those scripts needs to either be in the onload handler, in some function called from the onload handler or guarenteed not to execute until some time later (such as in an event handler that you're sure won't happen before the script finishes loading).
To explain further, I've added some annotations to your code:
function loadScript(url,callback){
var script = document.createElement("script");
script.type = "text/javascript";
script.id="acvDataRequest";
document.getElementsByTagName("head")[0].appendChild(script);
if (script.readyState){ //IE
script.onreadystatechange = function(){
if (script.readyState == "loaded" ||
script.readyState == "complete"){
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function(){
// ** your script is now loaded here **
alert(dataHeader) // I CAN SEE MY OBJECT FROM LOADED SCRIPT
callback();
};
}
script.src = url;
// ** your script is in the process of loading here and has likely not completed **
alert(dataHeader); // IT SAYS UNDEFINED
}

Sporadic error when initializing Twitter widgets

On a site we run a basic Twitter button, which works fine 90% of the time. Occasionaly the initialization fails with the error: Uncaught TypeError: Cannot call method 'load' of undefined.
This is the script that does the Twitter initialization:
<script type="text/javascript">
//<![CDATA[
(function() {
var twitterScriptTag = document.createElement('script');
twitterScriptTag.type = 'text/javascript';
twitterScriptTag.async = true;
twitterScriptTag.src = document.location.protocol + '//platform.twitter.com/widgets.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(twitterScriptTag, s);
})();
//]]>
</script>
Can anybody give a hint why this happens?
UPDATE: After setting async = false I get the following error:
'twttr.widgets' is Null or no object
SOLUTION: I load some stuff via AJAX on $(document).ready(). Problem is, when the AJAX content loads faster than the Twitter initialization is done it fails.

Categories

Resources