A playlist of JavaScript For Loop - executing successive Ajax calls

Requesting Assistance! I am encountering numerous conflicting results in my search for a solution to this issue. The objective is to create a playlist from a dynamically generated list of songs, ensuring that each song plays consecutively and the iframe for YouTube or SoundCloud is loaded sequentially using AJAX.

The list of songs is fetched from the YouTube and SoundCloud APIs and displayed as an unordered list. Each song's anchor tag is assigned an ID as it loads into the browser.

//List Item
echo "<a id=\"" . $i . "\" href=\"javascript:void(0)\" onclick=\"play_clicked('youtube',".$i.",".$song_count.")\">
                            <li class = \"song\">";

The first song receives the ID 0, the second song gets 1, and so on. Additionally, the media ID of each song is added to a JavaScript array while they load, associating the song's ID with the key where its media ID is stored in the array.

echo 
'<script type="text/javascript">

track_id_array.push("'.$vid_id.'");

</script>';

A JavaScript function is created to handle when a song is clicked:

function play_clicked(api_type,clicked_key,song_count)

This function takes parameters for API type - SoundCloud or YouTube, the anchor ID or array key containing the clicked media ID, and the total number of songs in the list. It utilizes a for loop to iterate through the array of media IDs:

for (var i=clicked_key; i<=song_count; i++){

The loop starts from the ID of the clicked song and proceeds to process the subsequent songs. Firstly, it checks if the media ID exists in the array:

if(window.track_id_array[i])

If found, this should hold the media ID such as a YouTube ID like "6_8ZZtL6qmM". Subsequently, it determines whether it is a SoundCloud or YouTube song, executing an AJAX call to embed the ID into a HTML5 iframe widget specifically designed for these platforms.

$vid_id = $_GET[id];

//YouTube player embed
echo '<iframe width="498" height="280" src="http://www.youtube.com/embed/'.$vid_id. '?autoplay=1" frameborder="0" allowfullscreen></iframe>
';

The embedded content is then returned to a div within the main page, allowing the respective song to play in the designated widget. To implement the playlist functionality, the plan involves initiating the loop from the clicked song's ID/key, fetching the corresponding media ID from the array, making the appropriate API call via AJAX, setting a timeout according to the song's duration, and moving on to the next key in the array upon completion of the song.

My familiarity with JavaScript is limited, and employing client-side code for this task is not preferred. Is the approach described here feasible, or am I approaching it incorrectly? I aim to execute the AJAX calls sequentially in the loop, avoiding simultaneous requests. When implementing the entire function, some unexpected outcomes were observed. Instead of playing all songs sequentially, only the last song in the list was played. Any insights into why this may be happening would be greatly appreciated!

//Play selected track and subsequent tracks
function play_clicked(api_type,clicked_key,song_count){

function showPlayTrack() {
                    if (xhr.readyState == 4) {
                    if (xhr.status == 200) {
                        var outLink = xhr.responseText;
                    }
                    else {
                        var outLink = "There was a problem with the request" + xhr.status;
                    }
                    }
                    var vis = parent.document.getElementById("play_content");

                    vis.innerHTML = outLink;

                    setTimeout(300000);
}   


for (var i=clicked_key;i<=song_count;i++){

    if(window.track_id_array[i]){

        if(api_type == "scloud"){

                var soundcloud_id = window.track_id_array[i];

                if (window.XMLHttpRequest) {
                xhr = new XMLHttpRequest();
                }
                else {
                    if (window.ActiveXObject) {
                        try {
                            xhr = new ActiveXObject("Microsoft.XMLHTTP");
                        }
                        catch (e) { 
                        }
                    }
                }

                if (xhr) {
                    xhr.onreadystatechange = showPlayTrack;
                    xhr.open("GET", "getsoundcloud.php?streamurl="+soundcloud_id, true);


                }
                else {
                    alert("Sorry, but I could't create an XMLHttpRequest");
                }



        }else if (api_type == "youtube"){


            var vid_id = window.track_id_array[i];

            if (window.XMLHttpRequest) {
                xhr = new XMLHttpRequest();
                }
                else {
                    if (window.ActiveXObject) {
                        try {
                            xhr = new ActiveXObject("Microsoft.XMLHTTP");
                        }
                        catch (e) { 
                        }
                    }
                }

                if (xhr) {
                    xhr.onreadystatechange = showPlayTrack;
                    xhr.open("GET", "getyoutube.php?streamurl="+vid_id, true);
                    xhr.send(null);

                }
                else {
                    alert("Sorry, but I could't create an XMLHttpRequest");
                }

        }
    }
}
}

Answer №1

After some experimentation, I came up with a solution that involves utilizing recursive function calls. When the user clicks, the play function is triggered. This function reads the media id, verifies the api type, increments the key, and then makes an ajax call to fetch the iframe. Upon successful retrieval of the iframe, it is inserted into the appropriate div. The function then waits for the length of the song before recursively calling the initial play function again with the updated key as a parameter. There are still a few details to iron out, such as adjusting the playback time if the user seeks within the media. Overall, however, this approach proves to be a promising playlist solution!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for troubleshooting aspx pages following an ajax post back?

I am currently working on a project with a unique architecture. During the page_load event, we utilize a switch case structure: switch (command) { case "LOAD": load(); break; case "UNLOAD": ...

Using jquery mobile to implement an event handler for the close button on a page dialog

Is it possible to trigger a callback before closing a dialog-style page when the close button is clicked? I want to catch and handle the click event of the close button on the dialog page. <div data-role="page" id="page1"> <div data-role="he ...

Is it necessary to close the browser for jQuery to reload an XML document?

I've successfully used jQuery's $.ajax to retrieve an xml value in my code. However, I'm facing an issue where any changes made to the xml document are not reflected upon a browser refresh. Specifically, the new saved xml value xmlImagePath ...

What is the method to create a resizable table column border rather than resizing the bottom corner border?

At the moment, we are able to resize the table border when we drag the corner. However, my goal is to enable resizing on the right side of the full border. https://i.sstatic.net/yFI24.png Below is the CSS code for resizing: th{ resize: horizontal; ove ...

Utilize Set.Attribute prior to entering the for loop

Could someone please clarify why I am unable to declare the var node before the for loop and then simply use appendChild(node) inside the loop? Why is it necessary to declare it for each iteration in order for it to affect all div elements? Otherwise, it w ...

Updating the style of a div in ReactJS with instant changes

Currently working on a project where I need to create a self-centering, self-sizing content editable div. The text is centered and the width is already set to 100% of the parent container; my main concern now is the height. I have implemented a function t ...

Navigate to the Vuejs component's element that has a specified class name

When a component is loaded, I want it to automatically scroll down to display the element with a class name of 'actual-month' within an unordered list. <b-card no-body header="<i class='fa fa-align-justify'></i> Unorder ...

Can anyone assist with troubleshooting the font size issue for a JavaScript tooltip on Joomla 1.5 with CK Forms?

My Joomla 1.5 site has CK Forms installed and is functioning properly, except for one issue: the tooltip on the captcha is not displaying correctly. It appears in a tiny 1px font size. Even though I have tried debugging using Firebug and confirmed that the ...

Encountered an issue with a module not being found while trying to install a published React component library that is built using Rollup. The error message states:

In my latest project, I have developed a React component library called '@b/b-core' and used Rollup for building and publishing to the repository. When trying to install the library in a React app, an issue arises where it shows Module not found: ...

Concurrent iteration using a `for` loop to generate an array as the result

Is it possible to run a for loop in parallel to utilize all the processors on a Windows machine and generate a 3-dimensional array as a result? Currently, the code I am using takes about an hour to execute and looks like this: guad = array(NA, c(1680, 170 ...

Passing the value of the selected calendar date to the controller

How can I pass the value generated by this calendar_date_select to the controller? Any suggestions on how to modify the onchange code? <%= calendar_date_select_tag "meeting_date_1", @time, :embedded => true, :time => true, :minut ...

The Art of Checkbox Design

Seeking help in replacing the default check mark on a checkbox with an image. Here is the code snippet I am currently using: <html> <head> <style> .bl { background:-webkit-gradient(linear, left top, left bottom, color-stop(0, #175899), c ...

The input field automatically populates with the username that has been stored in the browser's form

Issue: I have created an input field with the type text, but upon page load, it gets automatically filled with a username saved in the browser's form data for this website's login page. I want it to show up clean when the page loads. <input t ...

I must generate numerous copies of my CSS class using JavaScript

My CSS includes a base class named "toast" that contains basic styling, along with a JavaScript function that generates different types of toasts based on user input. The function modifies the toast class by inserting icons and text as demonstrated below: ...

The Datetimepicker component outputs the date in datetime format rather than a timestamp

Currently, I am utilizing the datetimepicker JavaScript script with specific implemented logic: <script> var today = new Date(); var dd = today.getDate(); var mm = today.getMonth(); var yy = today.getF ...

Tips for correctly loading all elements on an HTML page before making CSS modifications

This question has been asked several times in the past. I am asking because when I used the on ready callback in jQuery, it did not change the placeholder text of my element "search_input". $( document ).ready(function() { $("#search_input").attr(' ...

I am struggling to decide which attribute to use for implementing image swap on mouseover() and mouseout()

I have a problem using jQuery to switch between images when hovering on and off. Here's the code snippet I'm working with: HTML <img class="commentImg" src="images/comments.png" data-swap="images/comment_hover.png" alt=""> jQuery $(" ...

Reactjs - There was an error: $node.attr(...).tooltip is not defined

I am currently troubleshooting the SummerNote mention library and encountering an issue - Uncaught TypeError: $node.attr(...).tooltip is not a function The versions I am using are: - "react-summernote": "^2.0.0", - React version: "react": "^16.8.6", ...

Get rid of the unnecessary vertical line that is located at the end of the string

I have come across a situation similar to the one demonstrated in this code snippet: http://plnkr.co/edit/eBjenGqgo3nbnmQ7XxF1?p=preview Currently, I am working with AngularJS 1.5.7. The directives used in my input - ( first ) textarea are the same as tho ...

The parameter type 'string | null' cannot be assigned to the value function 'ValueFn<SVGPathElement, Datum[], string | number | boolean | null>'

I recently delved into the world of d3 and attempted to create a simple line chart using d3, TypeScript, and react. However, I keep encountering a TypeScript error whenever I try to implement it. Strangely, I can briefly see my chart before it disappears a ...