
/********
 * Models
 ********/


/******************************************
 * Subjects -- a collection of subject data
 */
function Subjects(apiKey) {
    baseUrl = 'http://api.dp.la/v2/items?callback=?'
    this.apiKey = apiKey;
    this.url = baseUrl + '&api_key=' + apiKey;
}

/* get
 * ---
 * Given a callback, execute it by passing an Array of subject strings
 */
Subjects.prototype.get = function(opts) {
    successCb = (opts['successCb'] || function() {});
    failCb = (opts['failCb'] || null);

    $.jsonp({
        'url': this.url,
        'data': {
            'fields': 'sourceResource.subject',
            // We're cheating and selecting subjects where subject matches "cat"
            // in order to avoid records with empty subjects.
            'sourceResource.subject': 'cat'
        },
        'cache': true,
        'success': function(data) {
            successCb(data);
        },
        'error': function() {
            // If we could avoid using JSONP, and use $.ajax() instead, we would
            // have available much more information in the error response for
            // providing better feedback and diagnostics.  We have to use JSONP,
            // however, for a browser-based application that uses the DPLA API
            // but is not served from the api.dp.la domain.
            alert('Failed to retrieve subjects.');
        }
    });
};


/*******
 * Views
 *******/


/***************************************
 * SubjectListView -- a list of subjects
 *
 * params:
 * - $parent:  DOM element
 * - apiKey:   API key string
 */
function SubjectListView($parent, apiKey) {
    _.bindAll(this, 'render', 'drawList', 'noData', 'drawPreformatted');
    this.$parent = $parent;
    this.subjects = new Subjects(apiKey);
}

/* render
 * ------
 * Render the view
 */
SubjectListView.prototype.render = function() {
    this.subjects.get({'successCb': this.drawList});
};

/* drawList
 * --------
 * Draw an unordered list of subject strings
 */
SubjectListView.prototype.drawList = function(data) {
    if (data['docs'].length) {
        $list = $('<ul>');
        _.each(data['docs'], function(doc) {
            _.each(doc['sourceResource.subject'], function(subj) {
                $li = $('<li>');
                $li.text(subj['name']);
                $list.append($li);
            });
        });
        this.$parent.append($list);
    } else {
        this.noData();
    }
};

/* noData
 * ------
 * Draw a response for no data
 */
SubjectListView.prototype.noData =  function() {
    $p = $('<p>');
    $p.text('No data');
    this.$parent.prepend($p);
};

/* drawPreformatted
 * ----------------
 * For debugging:  draw a JSON string for the given data
 */
SubjectListView.prototype.drawPreformatted = function(data) {
    this.$parent.html('<pre>' + JSON.stringify(data) + '</pre>');
};


/* Pulled from JavaScript: The Definitive Guide */
function getArgs() {
    var args = {};
    var query = location.search.substring(1);
    var pairs = query.split('&');
    for (var i = 0; i < pairs.length; i++) {
        var pos = pairs[i].indexOf('=');
        if (pos == -1) continue;
        var argname = pairs[i].substring(0, pos);
        var value = pairs[i].substring(pos + 1);
        value = decodeURIComponent(value);
        args[argname] = value;
    }
    return args;
}


function main() {
    apiKey = (getArgs()['api_key'] || null);
    if (apiKey) {
        slView = new SubjectListView($('#main'), apiKey)
        slView.render();
    } else {
        alert('Please fill in your API key with the query parameter api_key.');
    }
}

@@ -407,20 +407,25 @@
 opts) %7B%0A
+%0A
     
+var 
 successC
@@ -470,16 +470,20 @@
 %7D);%0A    
+var 
 failCb =
@@ -508,16 +508,37 @@
 %7C null);
+%0A    var that = this;
 %0A%0A    $.
@@ -909,22 +909,122 @@
     
-successCb(data
+docs = (data.docs %7C%7C %5B%5D);  // probably assigned, but be paranoid%0A            successCb(that.subjectsFromDocs(docs)
 );%0A 
@@ -1515,16 +1515,391 @@
 %7D);%0A%7D;%0A%0A
+/*%0A * subjectsFromDocs%0A * ----------------%0A * Given a DPLA API 'docs' object, return an array of all of the subject strings%0A */%0ASubjects.prototype.subjectsFromDocs = function(docs) %7B%0A    subjects = %5B%5D;%0A    _.each(docs, function(doc) %7B%0A        _.each(doc%5B'sourceResource.subject'%5D, function(s) %7B%0A            subjects.push(s.name);%0A        %7D);%0A    %7D);%0A    return subjects;%0A%7D;%0A%0A
 %0A/******
@@ -2539,36 +2539,44 @@
 ion(
-data) %7B%0A    if (data%5B'docs'%5D
+subjectNames) %7B%0A    if (subjectNames
 .len
@@ -2628,86 +2628,20 @@
 ach(
-data%5B'docs'%5D, function(doc) %7B%0A            _.each(doc%5B'sourceResource.
 subject
-'%5D
+Names
 , fu
@@ -2651,20 +2651,16 @@
 ion(
-subj) %7B%0A    
+name) %7B%0A
     
@@ -2696,20 +2696,16 @@
         
-    
 $li.text
@@ -2709,20 +2709,12 @@
 ext(
-subj%5B'
 name
-'%5D
 );%0A 
@@ -2720,28 +2720,24 @@
             
-  
-  
 $list.append
@@ -2747,24 +2747,8 @@
 i);%0A
-            %7D);%0A
     

Refactor Subjects.get