Reputation: 1959
I'm new to using $.when
and $.Deferred()
, and I can't seem to get them to work
What I'm trying to do is run a few functions, and when they've all finished trigger a final function
Here are a couple of options I've tried
Option 1 - Returning d1.getRating is not a function
(this is a function further up in the script) following docs from JQuery as I understood them
// Set Deferred
var d1 = $.Deferred();
// Return movie information
if (idResp[0].type === "movie") {
// Output Slug
traktSlug = 'movies/' + idResp[0].movie.ids.slug;
// Output
$.when(d1).done(function (ratingValue) {
console.log('Rating Is: ' + ratingValue);
outputIMDb(showCheckIn, traktSlug, ratingValue);
});
// Get Rating
d1.getRating(idResp[0].type, idResp[0].movie.ids.trakt);
}
Option 2 - Returning ratingValue is undefined
// Return movie information
if (idResp[0].type === "movie") {
// Output Slug
traktSlug = 'movies/' + idResp[0].movie.ids.slug;
// Output
$.when(getRating(idResp[0].type, idResp[0].movie.ids.trakt)).done(function (ratingValue) {
console.log('Rating Is: ' + ratingValue);
outputIMDb(showCheckIn, traktSlug, ratingValue);
});
}
Any suggestions or a nudge in the right direction would be much appreciated
Full source code can be viewed on GitHub
UPDATE
I realised after reading the JQuery docs again that resolve()
is not the name of a generic function, so I modified my code, but I'm still getting ratingValue is undefined
back
Updated Option 1 Code
// Set Deferred
var d1 = $.Deferred();
// Return movie information
if (idResp[0].type === "movie") {
// Output Slug
var traktSlug = 'movies/' + idResp[0].movie.ids.slug;
// Output Div
$.when(d1).done(function(ratingValue) {
console.log('Rating Is: ' + ratingValue);
outputIMDb(1, traktSlug, ratingValue);
});
// Get Rating
d1.resolve(getRating(idResp[0].type, idResp[0].movie.ids.trakt));
}
UPDATE 2
Sorry, my apologies for not including the getRating
function. As follows
// Get Rating
function getRating(type, id, season = 0, episode =0) {
var slugType = "";
switch (type) {
case "movie":
slugType = "movies";
break;
default:
slugType = "movies";
break;
}
var request = new XMLHttpRequest();
request.open('GET', 'https://api.trakt.tv/' + slugType + '/' + id + '/ratings');
request.setRequestHeader('Content-Type', 'application/json');
request.setRequestHeader('trakt-api-version', '2');
request.setRequestHeader('trakt-api-key', APP_KEY);
request.onreadystatechange = function () {
if (this.readyState === 4) {
// Get Response and put in array
var ratingsResp = JSON.parse(this.responseText);
// Return Rating
return Math.round(ratingsResp.rating * 10);
} else {
return 0;
}
};
request.send();
}
Upvotes: 0
Views: 603
Reputation: 19288
The main thing to do is to write getRating()
to return a promise. You could promisify XMLHttpRequest()
but it's much easier to use jQuery.ajax()
.
Here it is, based on the original code on GitHub :
function getRating(type, id, season=0, episode=0) { // mmm, formal defaults - odd for browser-based javascript.
var slugType;
switch(type) {
case 'movie':
slugType = 'movies';
break;
default:
slugType = 'movies';
}
return $.ajax({
url: 'https://api.trakt.tv/' + slugType + '/' + id + '/ratings',
headers: {
'Content-Type': 'application/json',
'trakt-api-version': '2',
'trakt-api-key': APP_KEY
},
dataType: 'json'
}).then(function(response) {
return Math.round(response.rating * 10);
}).then(null, function(xhr, textMessage, errorThrown) {
console.error('getRating error: ', textMessage);
return $.when(0); // error recovery.
});
}
Then, use jQuery.ajax()
in the main routine too :
chrome.storage.local.get('access_token', function(result) {
var ACC_TOK = result.access_token;
if (ACC_TOK && typeof ACC_TOK !== undefined) {
if (tabURL.includes('imdb.com')) {
$.ajax({
url: 'https://api.trakt.tv/search/imdb/' + tabURL.match(/tt\d{7}/),
headers: {
'Content-Type': 'application/json',
'trakt-api-version': '2',
'trakt-api-key': APP_KEY
},
dataType: 'json'
}).then(function(idResp) {
if(idResp[0].type === 'movie') {
return getRating(idResp[0].type, idResp[0].movie.ids.trakt).then(function(ratingValue) {
console.log('Rating Is: ' + ratingValue);
outputIMDb(1, 'movies/' + idResp[0].movie.ids.slug, ratingValue);
});
} else {
console.log("Type: " + idResp.type);
}
}).fail(function(xhr, textMessage, errorThrown) {
console.error(textMessage);
});
}
}
});
Note that because jQuery.ajax()
returns a promise, there's no need to generate/resolve your own jQuery.Deferred()s
.
Code above may not be 100% correct but should go a considerable distance to a working solution.
Upvotes: 1