2

I am querying an API that I made for my site which returns data in this format:

{
   "success":true,
   "code":1,
   "quantity":3,
   "classes":[
      [
         {
            "name":"ECEC 301 Advanced Programming for Engineers Lab",
            "days":"W",
            "times":"09:00 am - 10:50 am",
            "crn":"11216"
         },
         {
            "name":"ECEC 301 Advanced Programming for Engineers Lecture",
            "days":"T",
            "times":"02:00 pm - 03:20 pm",
            "crn":"11215"
         },
         {
            "name":"ECEC 302 Digital Systems Projects Lab",
            "days":"MW",
            "times":"03:00 pm - 04:50 pm",
            "crn":"12567"
         }
      ],
      [
         {
            "name":"ECEC 301 Advanced Programming for Engineers Lab",
            "days":"W",
            "times":"09:00 am - 10:50 am",
            "crn":"11216"
         },
         {
            "name":"ECEC 301 Advanced Programming for Engineers Lecture",
            "days":"T",
            "times":"02:00 pm - 03:20 pm",
            "crn":"11215"
         },
         {
            "name":"ECEC 302 Digital Systems Projects Lab",
            "days":"TR",
            "times":"09:00 am - 10:50 am",
            "crn":"13523"
         }
      ],
      [
         {
            "name":"ECEC 301 Advanced Programming for Engineers Lab",
            "days":"F",
            "times":"02:00 pm - 03:50 pm",
            "crn":"11217"
         },
         {
            "name":"ECEC 301 Advanced Programming for Engineers Lecture",
            "days":"T",
            "times":"02:00 pm - 03:20 pm",
            "crn":"11215"
         },
         {
            "name":"ECEC 302 Digital Systems Projects Lab",
            "days":"MW",
            "times":"03:00 pm - 04:50 pm",
            "crn":"12567"
         }
      ],
   "message":"3 schedule[s] were generated"
}

When the page loads, a panel queries this API like so:

    $.ajax({
        url: '{{ URL('schedulizer/schedules') }}',
        type: "GET",
        dataType: 'json'
    }).done(function(data){
        // Get the hash
        window.location.hash = '#1';
        var type = window.location.hash.substr(1);
        $("#classes").html(JSON.stringify(data.classes[type]));
    });

What it does is, it gets the URL hash (so #1 for example), and uses that as the index for the classes array from the JSON API. A query could contain many schedules, or no schedules at all.

I have some test HTML which are essentially buttons with a different hash value from the current one. I'm trying to see if I could cycle through the different indices of the JSON array:

<div class="panel panel-primary">
    <div class="panel-heading">
        <h3 class="panel-title">Schedule</h3>
    </div>
    <div id="classes" class="panel-body panel-options">
        <div class="btn-group">
            <a href='{{ URL('schedulizer/schedule#2') }}' class="btn btn-default"><</a>
            <a href='{{ URL('schedulizer/schedule#3') }}' class="btn btn-default">></a>
        </div>
    </div>
</div>

And the page looks like this. As you can see, there's one index of the JSON array, and the button.

enter image description here

The issue:

When I click the button, I see that the URL hash changes from #1 to #2 to #3, however, I do not see that the JSON changes.

The data returned from the classes object are arrays of arrays. I want to loop through those arrays of arrays using the buttons without reloading the page, and subsequently updating #classes

I'm pretty new to Javascript and asynchronous programming, so any help is much appreciated.

1 Answer 1

1

You just left one more step to achieve that:

  1. In your current posted structure, the $("#classes").html(JSON.stringify(data.classes[type])); will override your button, which make your buttons disappear, you should move them to other place.

  2. Save the response data in another variable, and add eventListener to the buttons, when click, base on the functionality, increase or decrease the index to show, and use .html as you used before to show the data, just remember to keep the response data and the index I mentioned visible to the click handler.

So you can write your code like this:

var result;
var index = 0;
$.ajax({
    url: '{{ URL('schedulizer/schedules') }}',
    type: "GET",
    dataType: 'json'
}).done(function(data){
    // Get the hash
    window.location.hash = '#' + (index + 1);
    // Save the response data to hash
    result = data;
    $("#classes").html(JSON.stringify(result.classes[index]));
});

$('.btn.btn-default').click(function(e) {
    // Prevent the page redirect to another page, as you have href on it.
    // Or you can remove the href on the anchors.
    e.preventDefault();
    // Prevent undesired behaviors happen when data is not retrieved yet.
    if (!result || !result.classes) {
        return;
    }
    // Calculate next index for data to show.
    // I use the text < or > here to check, better way may be add class left/right to each anchor.
    var next = $(this).text() === '<' ? -1 : 1;
    index = index + next;
    // Make the index in boundary.
    if (index >= result.classes.length) {
        index = 0;
    } else if (index < 0) {
        index = result.classes.length - 1;
    }
    // Add hash.
    window.location.hash = '#' + (index + 1);
    $("#classes").html(JSON.stringify(result.classes[index]));
});

Demo is at jsfiddle. Note that jsfiddle wrap the codes in an window.onload callback, it's recommend to do so, use domready or window.onload to wrap the codes.

Sign up to request clarification or add additional context in comments.

5 Comments

This worked. And this exactly what I wanted. My next step will be to format the JSON data into a nice looking format in that panel. Do you have any suggestions on this (I don't want you to do it for me)? I am quite new to working with AJAX.
I'd suggest you find some template engine, then you can write some html-like template, which you can specify what data will be put where, and then use the template with the data to generate the dom elements, and append (replace) to the target place.
Thank you. Also, I liked your suggestion of not using string comparison for <. Can you expand on what you mean by "add class left/right to each anchor"? You mean class="left"?
Yes, like class="btn btn-default left", than you can use $(this).is('.left') to decide whether your index should -1 or not. As you may want to change the anchor to some fantastic icons later, then the < can't be used to check left or right anymore.
Another way is to store in data-ATTR, you can assign it like data-direction="left", then you can use $(target).data('direction') to get that value, with the data- prefix, you don't need to worry about your naming of attributes conflict with the web's built-ins.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.