Search code examples
jquerysoundcloudsoundmanager2

Each loop returning duplicate data from Soundcloud API


I'm trying to list multiple tracks on the same page using the Soundcloud API. I want to loop over each DIV so it pulls the correct individual data using the /tracks API reference. However it just pulls the same data into each div (same artwork, same audio etc). If I do a console log of the variable for the /tracks API ID reference then it correctly loops through each div and correctly lists the different ID's. Why is it pulling in the correct ID's but then pulling in duplicate data?

enter image description here

$(document).ready(function() {

  // Loop over each mix
  $(".mix").each(function(){

    // Set the mix ID as a variable
    var mixID = $(this).data("mix");

    // Test it's getting correct unique track ID's
    console.log($(this).data("mix"));

    // Get the track meta data
    SC.get('/tracks/'+mixID+'', function(track) {
      var artwork = track.artwork_url;
      var artwork = artwork.replace('-large', '-t500x500');

      $(".mix__user").html(track.user.username).attr("href", track.user.permalink_url);
      $(".mix__artwork").attr("src", artwork);
      $(".mix__waveform").attr("src", track.waveform_url);
    });

    // Stream the track
    SC.stream('/tracks/'+mixID+'', function(sound) {

    var is_playing = false;

    // Track controls
    $('.mix__control').click(function(e) {
        e.preventDefault();

        if(is_playing === false){
            sound.start();
            is_playing = true;
            $(this).toggleClass("is_playing").html("Pause");

        } else if (is_playing === true) {
            sound.pause();
            is_playing = false;
            $(this).toggleClass("is_playing").html("Play");
        }
     });
   });
 });
});

There is some Craft CMS template language in the HTML.

{% for entry in craft.entries.section('mix') %}
    <article class="mix" data-mix="{{ entry.mixId }}">

    <div class="mix-meta">
            <button class="mix__control  ss-icon">Play</button>
            <img class="mix__artwork" src="">           
        <img class="mix__waveform" src="">
        </div>

      <a href="{{ entry.url}}" class="mix-wrap">
        <h1 class="mix__title">{{ entry.title }}</h1>
        <time class="mix__date" datetime="2008-02-14 20:00">{{ entry.postDate.format('d F Y') }}</time>

        <ol class="mix__tracklist">
        {% for block in entry.tracklisting %}
            {% if block.type == "tracklist" %}
                <li><span class="mix__artist">{{ block.artist }}</span> - <span class="mix__track">{{ block.track }}</span></li>
            {% endif %}
        {% endfor %}
        </ol>
      </a>
    </article>
{% endfor %}

Solution

  • Looking at your code, my guess is that you're running into a problem with your jquery selectors updating every $(".mix__XXXX") on your page when you really only want to update the ones in the current <article class="mix">. You would want to change those selectors to $(this).find(".mix__XXXX");

    Bonus tip: assigning $(this) to a variable to like $this = $(this) will keep jquery from having to run it's wrapping function every time.

    Update with closure: (untested)

    (function($theMix) {    
        SC.get('/tracks/'+mixID+'', function(track) {
          var artwork = track.artwork_url;
          var artwork = artwork.replace('-large', '-t500x500');
    
          $theMix.find(".mix__user").html(track.user.username).attr("href", track.user.permalink_url);
          $theMix.find(".mix__artwork").attr("src", artwork);
          $theMix.find(".mix__waveform").attr("src", track.waveform_url);
        });
    })($(this));