freeCodeCamp / CurriculumExpansion

Creative Commons Attribution Share Alike 4.0 International
313 stars 105 forks source link

JSON APIs and AJAX #27

Closed erictleung closed 7 years ago

erictleung commented 8 years ago

The "JSON APIs and AJAX" challenges have been needing an upgrade for sometime now.

@MayankPratap is in charge of coordinating the expansion of these challenges, but he needs your help.

For each challenge, please reply to this GitHub issue with:

  1. Challenge description text
  2. Test suite (using the assert method)
  3. The seed code, which is pre-populated in the editor at the beginning of the challenge
  4. A working solution that makes all tests pass

We still need to come up with a list of concepts to cover, where each topic can be taught interactively, then translate these concept into the names of the challenges.

Some places to look for content to teach:

Here are the challenges we have planned till now :

You can suggest or add more challenges.

MayankPratap commented 8 years ago

I recently submitted an add-on to firefox. My add-on basically fetches data from an API(which was developed by me) and posts content to DOM dynamically. They rejected it saying that I have not sanitized the strings before inserting it into DOM. I think we should add a challenge on this. But I am not able to think how to form a challenge for this .

QuincyLarson commented 8 years ago

@erictleung Thanks for creating this issue. I added a checklist of current challenges.

QuincyLarson commented 8 years ago

@MayankPratap string sanitization would be a great challenge to add to our applied security challenges (https://github.com/FreeCodeCamp/CurriculumExpansion/issues/25)

Greenheart commented 8 years ago

An idea for "Convert JSON Data to HTML" - Use ES6 Template strings, but make sure to sanitize the JSON first.

QuincyLarson commented 8 years ago

@erictleung @MayankPratap would either of you be interested in being the topic owner and overseeing the design of these challenges?

alayek commented 8 years ago

Should we use fetch() API?

Greenheart commented 8 years ago

@alayek fetch() has a decent browser support so many campers will be able to work with it. And since fetch will be the future standard, it's probably a good idea to teach it.

An alternative is to start with the XMLHttpRequest since many older applications depends on it and it'll be around in legacy code for a significant time.

MayankPratap commented 8 years ago

Instead of getJSON we should use XMLHttpRequest in our challenges because it can support GET as well as POST. Also it would be great if we could add some challenges for posting data using AJAX.

QuincyLarson commented 8 years ago

I agree that we could move away from the jQuery helper methods and use the widely supported native JavaScript methods for this.

MayankPratap commented 8 years ago

@QuincyLarson I am planning to modify existing challenges(using only javaScript) and add some new challenges. I was wondering if I could get access to test suites of existing JSON API and ajax challenges ? Those would help me in creating test suites for new challenges.

Greenheart commented 8 years ago

@MayankPratap I think the tests can be found with all information about the challenges somewhere in the seed- directory in FCC's main repo

alayek commented 8 years ago

@MayankPratap ping me when you are free. I will show you the tests you are looking for.

MayankPratap commented 8 years ago

@alayek Thanks :+1: I have pinged you

MayankPratap commented 8 years ago

Get JSON with XMLHttpRequest Method

Challenge Description

You can also request data from an external source. This is where APIs come into play.

Remember that APIs - or Application Programming Interfaces - are tools that computers use to communicate with one another.

Most web APIs transfer data in a format called JSON. JSON stands for JavaScript Object Notation.

However, JSON transmitted by APIs are bytes, and your application receives it as string. They can be converted to JS Objects, but they are not JS Objects by default.

You've already been using JSON whenever you create a JavaScript object. JSON is nothing more than object properties and their current values, sandwiched between a { and a }.

These properties and their values are often referred to as "key-value pairs".

Let's get the JSON from Free Code Camp's Cat Photo API.

Here's the code you can put in your click event to do this:

    req=new XMLHttpRequest();
    req.open("GET",'/json/cats.json',true);
    req.send();
    req.onload=function(){
        json=JSON.parse(req.responseText);
        document.getElementsByClassName('message')[0].innerHTML=JSON.stringify(json);          
    };

Once you've added this, click the "Get Message" button. Your Ajax function will replace the "The message will go here" text with the raw JSON output from the Free Code Camp Cat Photo API.

Challenge Seed

      <script>
        document.addEventListener('DOMContentLoaded',function(){
            document.getElementById('getMessage').onclick=function(){
               // Only change code below this line.       
              // Only change code above this line.
           };
      });
     </script>
    <div class="container-fluid">
      <div class = "row text-center">
       <h2>Cat Photo Finder</h2>
     </div>
     <div class = "row text-center">
       <div class = "col-xs-12 well message">
         The message will go here
       </div>
     </div>
     <div class = "row text-center">
       <div class = "col-xs-12">
         <button id = "getMessage" class = "btn btn-primary">
          Get Message
         </button>
       </div>
     </div>
   </div>

Challenge Tests

//To be done.

Challenge Solution

      <script>
        document.addEventListener('DOMContentLoaded',function(){
            document.getElementById('getMessage').onclick=function(){
               req=new XMLHttpRequest();
               req.open("GET",'/json/cats.json',true);
               req.send();
               req.onload=function(){
                  json=JSON.parse(req.responseText);
                  document.getElementsByClassName('message')[0].innerHTML=JSON.stringify(json);          
              };
          };
     });
     </script>
    <div class="container-fluid">
      <div class = "row text-center">
       <h2>Cat Photo Finder</h2>
     </div>
     <div class = "row text-center">
       <div class = "col-xs-12 well message">
         The message will go here
       </div>
     </div>
     <div class = "row text-center">
       <div class = "col-xs-12">
         <button id = "getMessage" class = "btn btn-primary">
          Get Message
         </button>
       </div>
     </div>
   </div>

I am having trouble writing test cases using assert. Can any body help ?

MayankPratap commented 8 years ago

Convert JSON Data to HTML

Challenge Description

Now that we're getting data from a JSON API, let's display it in our HTML.

We can use the .forEach() method to loop through our data and modify our HTML elements.

First, let's declare an html variable with var html = "";.

Then, let's loop through our JSON, adding more HTML to that variable. When the loop is finished, we'll render it.

Here's the code that does this:

   json.forEach(function(val) {
      var keys = Object.keys(val);
      html += "<div class = 'cat'>";
      keys.forEach(function(key) {
        html += "<strong>" + key + "</strong>: " + val[key] + "<br>";
      });
      html += "</div><br>";
   });

Challenge Seed

<script>
  document.addEventListener('DOMContentLoaded',function(){
    document.getElementById('getMessage').onclick=function(){
       req=new XMLHttpRequest();
       req.open("GET",'/json/cats.json',true);
       req.send();
       req.onload=function(){
          json=JSON.parse(req.responseText);
          var html = "";
          // Only change code below this line

          // Only change code above this line
       };
   };
});
</script>
<div class="container-fluid">
  <div class="row text-center">
    <h2>Cat Photo Finder</h2> 
  </div>
  <div class="row text-center">
    <div class="col-xs-12 well message">
         The message will go here
    </div>
  </div>
  <div class="row text-center">
    <div class="col-xs-12">
    <button id="getMessage" class="btn btn-primary">
        Get Message
    </button>
  </div>
 </div>
</div>

Challenge Tests

// To be done.

Challenge Solutions

 <script>
   document.addEventListener('DOMContentLoaded',function(){
     document.getElementById('getMessage').onclick=function(){
        req=new XMLHttpRequest();
        req.open("GET",'/json/cats.json',true);
        req.send();
        req.onload=function(){
           json=JSON.parse(req.responseText);
           var html = "";
           json.forEach(function(val) {
                var keys = Object.keys(val);
                html += "<div class = 'cat'>";
                keys.forEach(function(key) {
                       html += "<strong>" + key + "</strong>: " + val[key] + "<br>";
                });
                html += "</div><br>";
           });
           document.getElementsByClassName('message')[0].innerHTML=html;
        };
    };
 });
  </script>
  <div class="container-fluid">
   <div class="row text-center">
     <h2>Cat Photo Finder</h2>
   </div>
   <div class="row text-center">
      <div class="col-xs-12 well message">
         The message will go here
      </div>
   </div>
   <div class="row text-center">
      <div class="col-xs-12">
        <button id="getMessage" class="btn btn-primary">
            Get Message
       </button>
     </div>
   </div>
 </div>
MayankPratap commented 8 years ago

Render Images from Data Sources

Challenge Description

We've seen from the last two lessons that each object in our JSON array contains an imageLink key with a value that is the URL of a cat's image.

When we're looping through these objects, let's use this imageLink property to display this image in an img element.

Here's the code that does this:

   html += "<img src = '" + val.imageLink + "' " + "alt='" + val.altText + "'>"; 

Challenge Seed

    <script>
    document.addEventListener('DOMContentLoaded',function(){
       document.getElementById('getMessage').onclick=function(){
           req=new XMLHttpRequest();
           req.open("GET",'/json/cats.json',true);
           req.send();
           req.onload=function(){
               json=JSON.parse(req.responseText);
               var html = "";
               json.forEach(function(val) {
                   html += "<div class = 'cat'>";
                   // Only change code below this line.

                   // Only change code above this line.
                   html += "</div><br>";
              });
              document.getElementsByClassName('message')[0].innerHTML=html;
         };
     };
  });
  </script>
 <div class="container-fluid">
  <div class = "row text-center">
    <h2>Cat Photo Finder</h2>
  </div>
  <div class = "row text-center">
    <div class = "col-xs-12 well message">
      The message will go here
    </div>
  </div>
  <div class = "row text-center">
    <div class = "col-xs-12">
      <button id = "getMessage" class = "btn btn-primary">
        Get Message
      </button>
    </div>
  </div>
</div>

Challenge Tests

// To be done.

Challenge Solution

    <script>
    document.addEventListener('DOMContentLoaded',function(){
       document.getElementById('getMessage').onclick=function(){
           req=new XMLHttpRequest();
           req.open("GET",'/json/cats.json',true);
           req.send();
           req.onload=function(){
               json=JSON.parse(req.responseText);
               var html = "";
               json.forEach(function(val) {
                   html += "<div class = 'cat'>";
                   html += "<img src = '" + val.imageLink + "' " + "alt='" + val.altText + "'>";
                   html += "</div><br>";
              });
              document.getElementsByClassName('message')[0].innerHTML=html;
         };
     };
  });
  </script>
 <div class="container-fluid">
  <div class = "row text-center">
    <h2>Cat Photo Finder</h2>
  </div>
  <div class = "row text-center">
    <div class = "col-xs-12 well message">
      The message will go here
    </div>
  </div>
  <div class = "row text-center">
    <div class = "col-xs-12">
      <button id = "getMessage" class = "btn btn-primary">
        Get Message
      </button>
    </div>
  </div>
</div>
MayankPratap commented 8 years ago

Trigger Click Events with javascript

Challenge Description

In this section, we'll learn how to get data from APIs. APIs - or Application Programming Interfaces - are tools that computers use to communicate with one another.

We'll also learn how to update HTML with the data we get from these APIs using a technology called Ajax.

We want our code to execute only once our page has finished loading. For that purpose we attach a event to our document called 'DOMContentLoaded'. Here's the code that does this:

 document.addEventListener('DOMContentLoaded',function(){
 });  

So Let's start by implementing a click event handler inside of our document.addEventListener('DOMContentLoaded',function(){ }); function by adding this code:

document.getElementById('getMessage').onclick=function(){};

After completing this, proceed to the next challenge where we will make our "Get Message" button change the text of the element with the class message.

Challenge Seed

   <script>
    document.addEventListener('DOMContentLoaded',function(){
          // Only change code below this line.

         // Only change code above this line.
    });
  </script>
  <div class="container-fluid">
     <div class = "row text-center">
        <h2>Cat Photo Finder</h2>
     </div>
     <div class = "row text-center">
        <div class = "col-xs-12 well message">
          The message will go here
        </div>
    </div>
   <div class = "row text-center">
      <div class = "col-xs-12">
         <button id = "getMessage" class = "btn btn-primary">
         Get Message
        </button>
      </div>
   </div>
</div>

Challenge Tests

// To be done.

Challenge Solution

   <script>
    document.addEventListener('DOMContentLoaded',function(){
          document.getElementById('getMessage').onclick=function(){
          };
    });
  </script>
  <div class="container-fluid">
     <div class = "row text-center">
        <h2>Cat Photo Finder</h2>
     </div>
     <div class = "row text-center">
        <div class = "col-xs-12 well message">
          The message will go here
        </div>
    </div>
   <div class = "row text-center">
      <div class = "col-xs-12">
         <button id = "getMessage" class = "btn btn-primary">
         Get Message
        </button>
      </div>
   </div>
</div>
alayek commented 8 years ago

@MayankPratap @QuincyLarson what do you think about teaching campers how to use some real, production grade APIs?

There are lot of good APIs out there that are commonly used in apps. Maybe we can ask the campers to create a token with GitHub or Facebook or Twitter and pull in some data, display in a page.

This is a common thing (all apps integrate with some common APIs in some way), and campers need to know how to read through the API documentation and write code that solves real-world problem.

We could even have fun exercise, like commenting on FB when it's someone's birthday or displaying Google Maps in a page. I understand it would be a bit complicated, so we can discuss the specifics.

But yes, there are some prerequisites to this steps:

Hence, we can either cover these here, or in some other module.

Oh, and, the campers need to know how CORS works, and what is JSONP.

MayankPratap commented 8 years ago

@alayek I agree. Codeforces API is a good real world API that is simple to use and does not require API key for most of the methods.

I once made a basic project using Codeforces API ,although using PHP, CF toolkit. Similarly we can add various challenges like fetching user's info and display them or comparing two users by their ratings. Campers will need to read through the documentation to solve these challenges.

Once camper uses this API and builds some confidence we can add challenges using facebook,twitter API etc.

For explaining CORS, we can ask campers to use FCC API seperately and since FCC API does not allow CORS , campers wont get any data from it.

QuincyLarson commented 8 years ago

@alayek @MayankPratap We could potentially create our own API endpoints. We are doing this with the current cat photo app. I was even considering a pass-through so that people could access local weather and other APIs through Free Code Camp, with our API keys obscured on the server.

Unless you need a particularly sophisticated API, I recommend we hard-code some example data instead, rather than becoming dependent on a service like Codeforces that's out of our control.

QuincyLarson commented 8 years ago

@erictleung @alayek @MayankPratap we should create a comprehensive list of all the challenges we want to build and replace the list in the OP with these. Then we can check these off as they are created.

@MayankPratap you have been the driving force behind the creation of these challenges so far. Would you be interested in "owning" this topic and coordinating contributions to it?

MayankPratap commented 8 years ago

@QuincyLarson Yes, that will be great.

QuincyLarson commented 8 years ago

@MayankPratap excellent! You are now the topic owner for this. See how many of these challenges you can get built by August 23 (the date we hope to start integrating all of these challenges into the codebase). If I can be of any help, just let me know :)

MayankPratap commented 8 years ago

@QuincyLarson @erictleung One more challenge that is very important is Posting data using AJAX. I am not able to edit the initial comment . Can someone add this to the list of challenges ?

QuincyLarson commented 8 years ago

@MayankPratap agreed. We definitely want to cover posting with AJAX.

I've given you write access to this repo.

MayankPratap commented 8 years ago

Prefilter JSON

Challenge Description

If we don't want to render every cat photo we get from our Free Code Camp's Cat Photo JSON API, we can pre-filter the json before we loop through it.

Let's filter out the cat whose "id" key has a value of 1.

Here's the code to do this:

   json = json.filter(function(val) {
      return (val.id !== 1);
   });

Challenge Seed

 <script>
   document.addEventListener('DOMContentLoaded',function(){
      document.getElementById('getMessage').onclick=function(){
          req=new XMLHttpRequest();
          req.open("GET",'/json/cats.json',true);
          req.send();
          req.onload=function(){                
          json=JSON.parse(req.responseText);                    
          var html = "";
          // Only change code below this line.                                                                                                                                              

         // Only change code above this line. 
         json.forEach(function(val) {
              html += "<div class = 'cat'>"
              html += "<img src = '" + val.imageLink + "'>"
              html += "</div>"
          });
          document.getElementsByClassName('message')[0].innerHTML=html;
       };
     }; 
  });
  </script>
   <div class="container-fluid">
      <div class = "row text-center">
         <h2>Cat Photo Finder</h2>
      </div>
      <div class = "row text-center">
        <div class = "col-xs-12 well message">
          The message will go here
        </div>
    </div>
   <div class = "row text-center">
      <div class = "col-xs-12">
         <button id = "getMessage" class = "btn btn-primary">
         Get Message
        </button>
      </div>
   </div>
 </div>

Challenge Tests

// To be done

Challenge Solution

 <script>
   document.addEventListener('DOMContentLoaded',function(){
      document.getElementById('getMessage').onclick=function(){
          req=new XMLHttpRequest();
          req.open("GET",'/json/cats.json',true);
          req.send();
          req.onload=function(){                
          json=JSON.parse(req.responseText);                    
          var html = "";
          json=json.filter(function(val){  
             return (val.id!==1);
          });
         json.forEach(function(val) {
              html += "<div class = 'cat'>"
              html += "<img src = '" + val.imageLink + "'>"
              html += "</div>"
          });
          document.getElementsByClassName('message')[0].innerHTML=html;
       };
     }; 
  });
  </script>
   <div class="container-fluid">
      <div class = "row text-center">
         <h2>Cat Photo Finder</h2>
      </div>
      <div class = "row text-center">
        <div class = "col-xs-12 well message">
          The message will go here
        </div>
    </div>
   <div class = "row text-center">
      <div class = "col-xs-12">
         <button id = "getMessage" class = "btn btn-primary">
         Get Message
        </button>
      </div>
   </div>
 </div>
MayankPratap commented 8 years ago

Posting data using XMLHttpRequest Method

Challenge Description

Till now we received data from external resource. We can also send data to an external resource. We are required to know the URL of an external resource which supports AJAX requests.

JavaScript's XMLHttpRequest Method can also be used to post data to a server. Here's the code to do it :

req=new XMLHttpRequest();
req.open("POST",url,true);
req.setRequestHeader('Content-Type','text/plain');
req.onreadystatechange=function(){
    if(req.readyState==4 && req.status==200){
        document.getElementsByClassName('message')[0].innerHTML=req.responseText;
    }
 };
 req.send(userName);

Once you have entered your name in input box and click "Send Message" , your AJAX function will replace "Reply from Server will be here." with reply of server which in this case is your name appended with " loves cats".

Challenge Seed

<script>
   document.addEventListener('DOMContentLoaded',function(){
       document.getElementById('sendMessage').onclick=function(){

         var userName=document.getElementById("name").value;
         // Only change code below this line.          

         // Only change code above this line.
     };
  });
 </script>
  <div class="container-fluid">
    <div class="row text-center">
      <h2>Cat Friends</h2>
    </div>
   <div class="row text-center">
      <div class="col-xs-12 well message">
          Reply from Server will be here.
      </div>
   </div>

   <div class="row text-center">
      <div class="col-xs-12">
        <label>Your name:
           <input type="text" id="name"/>
        </label>
        <button id="sendMessage" class="btn btn-primary">
           Send Message
        </button>
     </div>
   </div>
 </div>

Challenge Tests

// To be done

Challenge Solution

<script>
   document.addEventListener('DOMContentLoaded',function(){
       document.getElementById('sendMessage').onclick=function(){

         var userName=document.getElementById("name").value;
         req=new XMLHttpRequest();
         req.open("POST",url,true);
         req.setRequestHeader('Content-Type','text/plain');
         req.onreadystatechange=function(){
             if(req.readyState==4 && req.status==200){
                   document.getElementsByClassName('message')[0].innerHTML=req.responseText;
              }
          };
          req.send(userName);

     };
  });
 </script>
  <div class="container-fluid">
    <div class="row text-center">
      <h2>Cat Friends</h2>
    </div>
   <div class="row text-center">
      <div class="col-xs-12 well message">
          Reply from Server will be here.
      </div>
   </div>

   <div class="row text-center">
      <div class="col-xs-12">
        <label>Your name:
           <input type="text" id="name"/>
        </label>
        <button id="sendMessage" class="btn btn-primary">
           Send Message
        </button>
     </div>
   </div>
 </div>
MayankPratap commented 8 years ago

Get Geolocation data

Challenge Description

Another cool thing we can do is access our user's current location. Every browser has a built in navigator that can give us this information.

The navigator will get our user's current longitude and latitude.

You will see a prompt to allow or block this site from knowing your current location. The challenge can be completed either way, as long as the code is correct.

By selecting allow you will see the text on the output phone change to your latitude and longitude.

Here's some code that does this:

if (navigator.geolocation){ 
   navigator.geolocation.getCurrentPosition(function(position) {  
        document.getElementById('data').innerHTML="latitude: "+ position.coords.latitude +  "<br>longitude: " +  position.coords.longitude;
    });
}

Challenge Seed

<script>
  // Only change code below this line.

  // Only change code above this line.
</script>
<div id = "data">
  <h4>You are here:</h4>

</div>

Challenge Tests

// Not done yet

Challenge Description

<script>
if (navigator.geolocation){ 
   navigator.geolocation.getCurrentPosition(function(position) {  
        document.getElementById('data').innerHTML="latitude: "+ position.coords.latitude +  "<br>longitude: " +  position.coords.longitude;
    });
}

</script>
<div id = "data">
  <h4>You are here:</h4>

</div>
QuincyLarson commented 8 years ago

I'm closing this and seeding it in.

MayankPratap commented 8 years ago

@QuincyLarson I was having problems preparing test cases for challenges. I talked to @alayek about this issue. I am just curious about who is adding challenge tests.

QuincyLarson commented 8 years ago

@MayankPratap I am in the process of transferring all the challenges to seed files, which will make writing tests easier because you'll be able to load up the challenge on your local computer. If you want to try to create tests at this point, you're welcome to.

I'm not sure what tools @alayek has been using to testing his tests. Perhaps he can tell us :)

alayek commented 8 years ago

@QuincyLarson @MayankPratap I think simple assert() style tests would suffice. Often developers use Mock REST libraries to test their API code, without having to run a full on back-end API.

We can also use some Backend-as-a-service type tools. Something like Firebase maybe?

@atjonathan FYI.

QuincyLarson commented 8 years ago

@MayankPratap yes, as @alayek said, we should be able to use assert style statements to verify that elements on the page are where they should be, with the right content. We use the Chai library to do this. Here's an example test:

assert(code.test(/href=('|\")#Home('|\")/gi), 'message: Fix the quotes around the <code>href</code> value "#Home" by either changing or escaping them.');
AlexKott commented 8 years ago

@MayankPratap Hope I understand the intention right, but shouldn't the first challenge be called "Listening on click events"? Or maybe you plan to trigger the click programmatically?

MayankPratap commented 8 years ago

@AlexKott "Listening on click events" also seems correct. But previous challenge was "Trigger Click Events with JQuery" and since this time we are doing with JavaScript so I renamed it "Trigger Click Events with JavaScript".

HKuz commented 8 years ago

Hi @MayankPratap and others - I'm going through this section now for the QA process, and can't seem to find the "Change Text with Click Events" challenge. Let me know if the topic is covered by another challenge - it's checked off at the top, but I don't see it here or in the seed file. Thanks!

MayankPratap commented 8 years ago

@HKuz I do not know how I forgot that . Sorry . I will add it as soon as I can.

HKuz commented 8 years ago

@MayankPratap no worries, just mention me when you post and I'll drop it into the json seed file 👍

HKuz commented 8 years ago

@QuincyLarson - quick question continuing off our discussion to use latest JS syntax in the challenges. There are a few examples in the code for this topic that use callback functions (forEach, some event listeners) that could be rewritten to use the arrow function syntax. Should I make these changes, or leave the code as is? Thanks 😄

QuincyLarson commented 8 years ago

@HKuz Great question. I think you can leave the code as-is. The arrow functions are just syntactic sugar - these aren't technically adding any new functionality.

@MayankPratap thanks for your help with this!

Also, I recently spoke with a camper who said she tried several other platform's AJAX tutorials, and she said one thing ours does not do very well is show what a JSON API response would look like. Can we add one or two challenges that show what these responses look like and how to parse them?

MayankPratap commented 8 years ago

Change Text with Click Events

Challenge Description

When our click event happens, we can use javaScript to update an HTML element.

Let's make it so that when a user clicks the "Get Message" button, we change the text of the element with the class message to say "Here is the message".

We can do this by adding the following code within our click event:

 document.getElementsByClassName('message')[0].innerHTML="Here is the message";

Challenge Seed

   <script>
    document.addEventListener('DOMContentLoaded',function(){
         document.getElementById('getMessage').onclick=function(){     
              // Only change code below this line.

             // Only change code above this line.
         }
    });
  </script>
  <div class="container-fluid">
     <div class = "row text-center">
        <h2>Cat Photo Finder</h2>
     </div>
     <div class = "row text-center">
        <div class = "col-xs-12 well message">
          The message will go here
        </div>
    </div>
   <div class = "row text-center">
      <div class = "col-xs-12">
         <button id = "getMessage" class = "btn btn-primary">
         Get Message
        </button>
      </div>
   </div>
</div>

Challenge Tests

// To be done.

Challenge Solution

   <script>
    document.addEventListener('DOMContentLoaded',function(){
         document.getElementById('getMessage').onclick=function(){     

            document.getElementsByClassName('message')[0].innerHTML="Here is the message";

         }
    })
  </script>
  <div class="container-fluid">
     <div class = "row text-center">
        <h2>Cat Photo Finder</h2>
     </div>
     <div class = "row text-center">
        <div class = "col-xs-12 well message">
          The message will go here
        </div>
    </div>
   <div class = "row text-center">
      <div class = "col-xs-12">
         <button id = "getMessage" class = "btn btn-primary">
         Get Message
        </button>
      </div>
   </div>
</div>
MayankPratap commented 8 years ago

@HKuz I have added challenge "Change Text with Click Events".

MayankPratap commented 8 years ago

Talk is Cheap, Show me JSON.

Challenge Description

In the previous challenge, we saw how to get JSON data from FCC Cat API.

Now lets see what different brackets and quotation marks represent in a JSON format.

[] -> These brackets represent array.

{} -> These brackets represent objects.

" " -> These represent a string.

In the Right Hand Side of this page you can click "Get Message Button" to see how a typical JSON data looks like.

The first and last character we see in the JSON data is square brackets [ ]. What does that mean ? It means that returned data is an array. But is it an array of numbers or array of strings or something else ?

The second character we see in the JSON data is flower bracket {. What do flower brackets represent? An object . So we can say that JSON data we see is an array of objects. We can see 3 outermost opening and closing flower brackets which tells us that there are three objects. So our array is an array of 3 objects.

We learnt earlier that objects contain "key-value pairs". Lets see whether current JSON objects have them. In out first object { } , we have "id":0 . Here "id" is a key and 0 is its corresponding value. Similarly we have "imageLink":"https://s3.amazonaws.com/freecodecamp/funny-cat.jpg".

Another interesting "key-value pair" in our first object is "codeNames":["Juggernaut","Mrs. Wallace","ButterCup"] . Here "codeNames" is the key and its value is an array of 3 strings. So we can have arrays of objects as well as arrays as keys and values.

The "key-value pairs" of an object are seperated by commas. Also the objects in an array of objects are seperated by commas.

In the next challenge we will see how to access different objects from an array of objects as well as how to access "key-value pairs" of an object.

Challenge Seed

      <script>
        document.addEventListener('DOMContentLoaded',function(){
            document.getElementById('getMessage').onclick=function(){
               req=new XMLHttpRequest();
               req.open("GET",'/json/cats.json',true);
               req.send();
               req.onload=function(){
                  json=JSON.parse(req.responseText);
                  document.getElementsByClassName('message')[0].innerHTML=JSON.stringify(json);          
              };
          };
     });
     </script>
    <div class="container-fluid">
      <div class = "row text-center">
       <h2>Cat Photo Finder</h2>
     </div>
     <div class = "row text-center">
       <div class = "col-xs-12 well message">
         The message will go here
       </div>
     </div>
     <div class = "row text-center">
       <div class = "col-xs-12">
         <button id = "getMessage" class = "btn btn-primary">
          Get Message
         </button>
       </div>
     </div>
   </div>

Challenge Tests

//To be done.

Challenge Solution

      <script>
        document.addEventListener('DOMContentLoaded',function(){
            document.getElementById('getMessage').onclick=function(){
               req=new XMLHttpRequest();
               req.open("GET",'/json/cats.json',true);
               req.send();
               req.onload=function(){
                  json=JSON.parse(req.responseText);
                  document.getElementsByClassName('message')[0].innerHTML=JSON.stringify(json);          
              };
          };
     });
     </script>
    <div class="container-fluid">
      <div class = "row text-center">
       <h2>Cat Photo Finder</h2>
     </div>
     <div class = "row text-center">
       <div class = "col-xs-12 well message">
         The message will go here
       </div>
     </div>
     <div class = "row text-center">
       <div class = "col-xs-12">
         <button id = "getMessage" class = "btn btn-primary">
          Get Message
         </button>
       </div>
     </div>
   </div>
MayankPratap commented 8 years ago

@QuincyLarson I have added a challenge to explain the JSON data returned in the challenge "Get JSON with XMLHttpRequest Method". Please suggest any edits if required .

QuincyLarson commented 8 years ago

@MayankPratap awesome! This looks great, other than the fact that it uses Bootstrap. I think @HKuz removed bootstrap from the other challenges and can do that for these, too.

What do you need in place so that you can write the tests for these?

HKuz commented 8 years ago

@MayankPratap - awesome, thanks! @QuincyLarson I'm currently working in this file, so I'll drop these in and review. I've been adding the tests as I go, they're mostly regex given the nature of the challenges.

For Bootstrap, this section does come after the Bootstrap one in the order - I took it out of the front end challenges because it wasn't covered until later. I can strip it out of these, though, and replace with some light weight CSS. I think the "well" class that's used in a few places is being deprecated in Bootstrap 4 anyways.

HKuz commented 8 years ago

All right, the new challenges are in the seed file and QA is basically done. @MayankPratap - the only challenge that didn't respond in the browser was for the "Post Data with the JavaScript XMLHttpRequest Method" one. In the line req.open("POST",url,true);, was the value for "url" supposed to be something specific? Or is this meant to be illustrative? Thanks 😄

MayankPratap commented 8 years ago

@HKuz In "Post Data with the JavaScript" challenge user will enter his name and on clicking "Send Message" name will be sent to the server which will then respond. Currently there is no FCC API which supports this and has to be added later. Once this feature is added to FCC API we can add the exact URL.

HKuz commented 8 years ago

Okay, thanks @MayankPratap for clarifying. @QuincyLarson I'll note that over in the QA issue to keep track of anything that needs functionality updates to run.

HKuz commented 8 years ago

Here's a first draft of some introduction text for this section. Any comments/reworks are welcome. It's meant to hit the following topics:

Note that this section uses an FCC API, so the intro doesn't include cross-domain requests or JSONP.

Introduction to the JSON APIs and Ajax Challenges

Similar to how User Interfaces help people use programs, Application Programming Interfaces (APIs) help programs interact with other programs. APIs are tools that computers use to communicate with one another, in part to send and receive data. You can use API functionality in your page once you understand how to make requests and process data from it. Programmers often use Ajax technologies when working with APIs.

The term Ajax originated as an acronym for Asynchronous JavaScript And XML. It refers to a group of technologies that make asynchronous requests to a server to transfer data, then load any returned data into the page. An asynchronous process has a couple key properties. The browser does not stop loading a page to wait for the server's response. Also, the browser inserts updated data into part of the page without having to refresh the entire page.

User experience benefits from asynchronous processes in several ways. Pages load faster since the browser isn't waiting for the server to respond in the middle of a page render. Requests and transfers happen in the background, without interrupting what the user is doing. When the browser receives new data, only the necessary area of the page refreshes. These qualities especially enhance the user experience for single page applications.

The data transferred between the browser and server is often in a format called JavaScript Object Notation (JSON). JSON resembles JavaScript object literal syntax, except that it's transferred as a string. Once received, it can be converted into an object and used in a script.

This section covers how to transfer and use data using Ajax technologies with a Free Code Camp API.