returning array from function in javascript
Question: so I come from a heavy python background, and I'm trying to wrap my head
around javascript. Here I have a function that returns an array of track IDs
for soundcloud songs by the artist 'v-2-followers'. How would I go about
assigning the output of SC.get(stuff) to a variable to reuse the track list in
another function. I'm sure I'm missing something fundamental. I'm less looking
for an answer that explains how to do this, but more **why** it's done like
that.

That said I would also very much appreciate the how. :)

    
    
    (function() {
    
        SC.initialize({
            client_id:'__CLIENTID__';
        });
    
        // Would like to set a variable equal to the output of
        SC.get('/tracks', { q: 'v-2-followers' }, function(tracks) {
            trackIdList = [];
            tracks.forEach(function(track){
                trackIdList.push(track.id);
            });
            return trackIdList;
        });
    
        // And use the variable here.
        SC.stream('/tracks/'+trackIdList[Math.floor(Math.random() * myArray.length)], function(sound) {
            sound.play();
            sound.pause();
            $('#fabrizio').hover(function(e){
                sound.resume();
            }, function(e){
                sound.pause();
            });
        });
    })();
    

I can see that I'm missing something fundamental about variable assignment and
scope, or function callbacks here. I've exhausted myself skimming docs on the
subject. If anyone can tell me how to do this, and more importantly, why it's
done that way, for future reference.


Answer: You have `trackIdList` as a global variable because it is not created using
`var`. So as it is, you can already access it from any other function. If you
wanted to limit its scope to just the outer function, add `var trackIdList;`
as the first line of your function. You should be declaring variables with
`var` everywhere in order to limit their scope.

    
    
    (function() {
        var trackIdList;
        ...
    })();
    

Further reading: [JavaScript Variable
Scope](http://stackoverflow.com/questions/500431/javascript-variable-scope)

The other concept you need to understand is regarding asynchronous execution
and callbacks in JavaScript. Your code that populates `trackIdList` is
contained within a callback function which is (most likely) called _after_
your call to `SC.stream()`. If `SC.stream()` depends on the value of
`trackIdList`, it should be called from the callback function.

It may help to illustrate what's going on by separating out your callback
functions.

    
    
    (function () {
        var trackIdList = [];
    
        SC.initialize({
            client_id: '__CLIENTID__'
        });
    
        SC.get('/tracks', { q: 'v-2-followers' }, processTracks);
    
        var randomIndex = Math.floor(Math.random() * myArray.length);
        SC.stream('/tracks/' + trackIdList[randomIndex], processSound);
    
        function processTracks(tracks) {
            tracks.forEach(function (track) {
                trackIdList.push(track.id);
            });
        }
    
        function processSound(sound) {
            sound.play();
            sound.pause();
            $('#fabrizio').hover(function (e) {
                sound.resume();
            }, function (e) {
                sound.pause();
            });
        }
    })();
    

`SC.get()` makes an asynchronous request and returns immediately. Then
`SC.stream()` is called _without waiting for the request to return_.
`processTracks()` isn't called until the request comes back. The trouble is
that `SC.stream()` depends on `processTracks()`, but is called immediately. To
fix this, call `SC.stream()` from the callback function of `SC.get()`:

    
    
    (function () {
        SC.initialize({
            client_id: '__CLIENTID__'
        });
    
        SC.get('/tracks', { q: 'v-2-followers' }, processTracks);
    
        function processTracks(tracks) {
            var trackIdList = [];
            tracks.forEach(function (track) {
                trackIdList.push(track.id);
            });
    
            var randomIndex = Math.floor(Math.random() * myArray.length);
            SC.stream('/tracks/' + trackIdList[randomIndex], processSound);
        }
    
        function processSound(sound) {
            sound.play();
            sound.pause();
            $('#fabrizio').hover(function (e) {
                sound.resume();
            }, function (e) {
                sound.pause();
            });
        }
    })();
    

