Best practice for nesting ajax calls - javascript

I am creating a simple app using Spotify REST API and JQuery where users can find an artist, and then it will show info about the artist, related artists, and most listened to songs on-page. I created 3 ajax calls which u can see below and everything works, but I think that it can be written in a better way (promises maybe?).
The first ajax call gets id from the server and create some DOM elements. The second two ajax calls need id to run and also create DOM elements. There is also a delete button that should delete DOM elements built from the data of each ajax call.
Is it possible to have it nested using the best practice or this is the only way possible?
artistForm.submit((e) => {
e.preventDefault();
let inputSearchQuery = artistInput.val();
let searchQuery = encodeURI(inputSearchQuery);
$.ajax({
url: `${baseUrl}search?q=${searchQuery}&type=artist`,
type: 'GET',
datatype: 'json',
headers: {
'Authorization': 'Bearer ' + accessToken
}
}).done((resp) => {
const artistId = (resp.artists.items[0].id);
// working with data and appending them on DOM
$.ajax({
url: `${baseUrl}artists/${artistId}/top-tracks?country=CZ`,
type: 'GET',
datatype: 'json',
headers: {
'Authorization': 'Bearer ' + accessToken
}
}).done((resp) => {
// working with data and appending them on DOM
$.ajax({
url: `${baseUrl}artists/${artistId}/related-artists`,
type: 'GET',
datatype: 'json',
headers: {
'Authorization': 'Bearer ' + accessToken
}
}).done((resp) => {
// working with data and appending them on DOM
deleteArtist.click(() => {
// need to have acces to data from every ajax call.
})
});
});
});
});

Given your work case, you could consider the following method:
artistForm.submit(async (e) => {
e.preventDefault();
let inputSearchQuery = artistInput.val();
let searchQuery = encodeURI(inputSearchQuery);
let artist = await $.ajax({
url: `${baseUrl}search?q=${searchQuery}&type=artist`,
type: 'GET',
datatype: 'json',
headers: {
'Authorization': 'Bearer ' + accessToken
}
});
const artistId = artists.items[0].id;
let topTracks = await $.ajax({
url: `${baseUrl}artists/${artistId}/top-tracks?country=CZ`,
type: 'GET',
datatype: 'json',
headers: {
'Authorization': 'Bearer ' + accessToken
}
});
let relatedArtists = await $.ajax({
url: `${baseUrl}artists/${artistId}/related-artists`,
type: 'GET',
datatype: 'json',
headers: {
'Authorization': 'Bearer ' + accessToken
}
});
deleteArtist.click(() => {
// need to have access to data from every ajax call.
});
});
This is assuming you are using jQuery 3.0 or higher. If not you can find a nice wrapper function here.
If you want to learn more about promises and async await I recommend the following video's: JavaScript Promises In 10 Minutes - by Web Dev Simplified
and The Async Await Episode I Promised - by Fireship.
If you have questions about the code above, please add a comment.
I hope this helps you continue with your project (and that you've learn something along the way 👍).

Related

How do I make an audio player with the Spotify Web API?

I was trying to make an audio player by starting with a play button. In my HTMl code i made a button:
Play
Then I used this code to make it play a song, but it doesnt seem to work.
document.getElementById('play').addEventListener('click', function() {
$.ajax({
url: 'https://api.spotify.com/v1/me/player/play',
type: 'PUT',
headers: {
'Authorization': 'Bearer ' + access_token
},
dataType: "json",
contentType: "application/json",
data: JSON.stringify({
"uris": ["spotify:track:"] + apiData.item.id,
"position_ms": apiData.progress_ms
})
});
});
apiData.item.id refers to the id of the currently playing track
apiData.progress_ms refers to the progress in milliseconds of currently playing track.
When I run my code and click on the play button, nothing happens. I don't know what I did wrong.
But I tried making a pause button by first making a button with an id called 'pause'. Then I did the following:
document.getElementById('pause').addEventListener('click', function() {
$.ajax({
url: 'https://api.spotify.com/v1/me/player/pause',
type: 'PUT',
headers: {
'Authorization': 'Bearer ' + access_token
},
dataType: "json",
contentType: "application/json",
data: JSON.stringify({
"uris": ["spotify:track:"] + apiData.item.id,
"position_ms": apiData.progress_ms
})
});
});
This is actually working! But I don't understand why the play button doesn't work and the pause button does.
Here is the documentation I used for both buttons:
https://developer.spotify.com/documentation/web-api/reference/player/start-a-users-playback/
https://developer.spotify.com/documentation/web-api/reference/player/pause-a-users-playback/
For the play button I got this error in the console log:
error 400
Can somebody help me out?
tl;dr: Working snippets at the bottom of this answer!
The uris field takes an array containing Spotify uris. This "uris": ["spotify:track:"] + apiData.item.id doesn't resolve to an array but to a string which is not what the endpoint awaits. Using [`spotify:track:${id}`] will work therefore.
This snippet shows the difference between the two.
console.log(["spotify:track:"] + id);
// Output with id = 1234: "spotify:track:1234" -> String
console.log([`spotify:track:${id}`]);
// Output with id = 1234: ["spotify:track:1234"] -> Array of strings
The reason the stop button works is that Spotify's pause endpoint doesn't use any of the data you passed in. The pause endpoint only has one optional query parameter called device_id. The data you passed along with it just gets ignored therefore. So the Ajax call for pause can be simplified as seen in the following snippets.
Here are two working snippets given that an access token is used that has the user-modify-playback-state scope authorized.
Play
$.ajax({
url: 'https://api.spotify.com/v1/me/player/play',
type: 'PUT',
headers: {
'Authorization': 'Bearer ' + access_token
},
dataType: "json",
contentType: "application/json",
data: JSON.stringify({
"uris": [`spotify:track:${apiData.item.id}`],
"position_ms": apiData.progress_ms
})
});
Pause
$.ajax({
url: 'https://api.spotify.com/v1/me/player/pause',
type: 'PUT',
headers: {
'Authorization': 'Bearer ' + access_token
}
});

Best method for getting JSON from REST API with Token

I have a rest API which has some nice JSON I want. I want to be able to call the API from a script within some HTML and pull out the JSON thats relevant to me.
What would be my best approach?
Something like the below using ajax? but i can't find a nice working example.
I have a token for my API so its vital I can use this. A curl command would be perfect, alas I cant do that. Eventually what I do will be used in a chrome extension.
jQuery.ajax( {
url: 'https://my-api.com/rest/v2/users/'
type: 'GET',
data: { content: 'testing test' },
beforeSend : function( xhr ) {
xhr.setRequestHeader( "Authorization", "BEARER " + xxxxxxxxx );
},
success: function( response ) {
// response
}
} );
Try this
var myJson;
$.ajax( {
url: 'https://my-api.com/rest/v2/users/'
type: 'GET',
data: { content: 'testing test' },
headers: { 'Authorization' = 'Bearer ' + token },
success: function( response ) {
myJson = response;
}
} );
Here there is the official explanation of the getJSON() method with some examples
https://api.jquery.com/jQuery.getJSON/
var authorizationToken = "xxxxxxx";
function xRequest(endpoint, method, options) {
$.ajax($.extend({}, {
type: method,
dataType: "json",
url: "https://api.xxxx.com/" + endpoint,
headers: {
"Authorization": "Token token=" + authorizationToken,
"Accept": "application/vnd.xxxxxx+json;version=2"
}
},
options));
}
This works

Getting a console.log from http.post data

I am trying to get a console log of the concatenated url, I have tried to create a new variable and then pass this to console.log with no success.
How can I get a log of the url I trying to post?
$scope.sendPaymentConfirmation = function (ordernumber) {
//function sendPaymentConfirmation(ordernumber) {
$http({
url: ('http://example.com/api/' + ordernumber), //'http://samedomain.com/GetPersons',
var posturl = url;
console.log(posturl);
method: "POST",
//data: postData,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
.then(function(response) {
// success : Thankyou, payment confirmation has been sent to the API server
window.alert('SUCCESS - Payment confirmation has been sent to the API server');
},
function(response) { // optional
// failed : ERROR There has been an error sending payment confirmation to the API server
window.alert('ERROR - There has been an error sending payment confirmation to the API server');
}
);
}
You need to understand that object literals cannot have statements and semicolons in them. If you don't want to do it the standard way #Quentin suggested, then you can do it like this (immediate function invocation):
$http({
url: (function(){
var posturl = 'http://example.com/api/' + ordernumber; //'http://samedomain.com/GetPersons',
console.log(posturl);
return posturl;
})(),
method: "POST",
//data: postData,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
You can't create a variable inside an object literal. Nor can you put any other arbitrary JS statements there.
Create the variable first. Then use it later.
var posturl = 'http://example.com/api/' + ordernumber
console.log(posturl);
$http({
url: posturl,

Itereate, store and visualize JSON structure

I'm trying to visualize data from a JSON structure, retrieved via a REST service. I'm retrieving 3 JSON structure via a REST service, and they are dependent on each other. This means that I am nesting 3 Ajax calls. Each ajax call collects data dependent on the ajax call before. Example:
I retrieve all tasks for an department in a company. Based on data about the tasks i retrieve data about the person who requested it. Finally i retrieve data about who the task was assigned to. My code:
$( document ).ready(function() {
$.ajax({
url: "http://helpdesk.site.com/IT/_vti_bin/ListData.svc/ITHelpdeskRequests?$filter=TaskStatusValue%20eq%20%27Not%20Started%27",
headers: { 'accept': 'application/json;odata=verbose', 'content-type': 'application/json;odata=verbose'},
success: function(data){
$.each(data.d.results, function(a, data) {
$.ajax({
url: "http://helpdesk.site.com/IT/_vti_bin/ListData.svc/ITHelpdeskRequests("+data.RequesterId+")/CreatedBy",
headers: { 'accept': 'application/json;odata=verbose', 'content-type': 'application/json;odata=verbose'},
success: function(data2){
$.ajax({
url: "http://helpdesk.site.com/IT/_vti_bin/ListData.svc/ITHelpdeskRequests("+data.AssignedToId+")/AssignedTo",
headers: { 'accept': 'application/json;odata=verbose', 'content-type': 'application/json;odata=verbose'},
success: function(data3){
$(".inner").prepend('<p>'+data.Request +' <br>Submitted by: '+data2.d.Name+'<br>Assigned to: '+data3.d.Name+' | Due in: '+data.DueInDays+' day(s)</p>');
for(var i = 0; i < data3.d.Name.length; i++)
{
var AssignedTo = data3.d.Name[i];
for(var j = 0; j < AssignedTo.length; j++)
{
var version = AssignedTo[j];
}
}
console.log(version);
}
});
}
});
});
}
});
});
I'm getting all the relevant data by running an $.each loop to run through the structure. What i want to do is visualize on a graph or heatmap how many tasks have been assigned to person. So i'm trying to store the data in a javascript array, but without luck. I can see that my data is getting displayed just fine if i try to prepend it.
The problem is that by running the $.each function i get multiple instances of the same person. I would like to have (as an example) a chart which shows the persons who have assigned tasks and how many tasks.
Any suggestions on how to store and/or visualize it?
EDIT Callback structure:
function getAssignedTo(data3) {
$(".inner").prepend('<p>' + data.Request + ' <br>Submitted by: ' + data2.d.Name + '<br>Assigned to: ' + data3.d.Name + ' | Due in: ' + data.DueInDays + ' day(s)</p>');
}
function getRequester(data2) {
$.ajax({
url: "http://helpdesk.site.com/IT/_vti_bin/ListData.svc/ITHelpdeskRequests(" + data.AssignedToId + ")/AssignedTo",
headers: {
'accept': 'application/json;odata=verbose',
'content-type': 'application/json;odata=verbose'
},
success: function getAssignedTo(data3)
});
}
function iterateResults(a, data) {
$.ajax({
url: "http://helpdesk.site.com/IT/_vti_bin/ListData.svc/ITHelpdeskRequests(" + data.RequesterId + ")/CreatedBy",
headers: {
'accept': 'application/json;odata=verbose',
'content-type': 'application/json;odata=verbose'
},
success: function getRequester(data2)
});
}
function getTasks(data) {
$.each(data.d.results, function iterateResults(a, data))
}
function getHelpData() {
$.ajax({
url: "http://helpdesk.site.com/IT/_vti_bin/ListData.svc/ITHelpdeskRequests?$filter=TaskStatusValue%20eq%20%27Not%20Started%27",
headers: {
'accept': 'application/json;odata=verbose',
'content-type': 'application/json;odata=verbose'
},
success: function getTasks(data)
});
}

Imgur API Version 3 JavaScript upload example

All the examples I find online are of earlier versions of the Imgur API or non JS code all of which uses an API key which doesn't exist in the newer API. Instead you get a client_id and secret. Anyone have example code that shows how an image can be uploaded to Imgur through JavaScript (or jQuery) using version 3 of their API?
$.ajax({
url: 'https://api.imgur.com/3/image',
headers: {
'Authorization': 'Client-ID YOUR_CLIENT_ID'
},
type: 'POST',
data: {
'image': 'helloworld.jpg'
},
success: function() { console.log('cool'); }
});
Building on #vin's example here is one:
$(document).ready(function() {
$.ajax({
url: 'https://api.imgur.com/3/image',
headers: {
'Authorization': 'Client-ID a1b2c3d4e5'
},
type: 'POST',
data: {
'image': image
},
success: function(data, status) {
console.log("Data: " + data.data.link + "\nStatus: " status);
console.log(data.data.link)
}
});
});
This lets you save the url to the file.

Categories

Resources