{
"name": "JSON APIs and AJAX",
"order": 2,
"time": "2 hours",
"helpRoom": "Help",
"required": [
{
"link":
"https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css"
}
],
"challenges": [
{
"id": "587d7fad367417b2b2512be1",
"title": "Handle Click Events with JavaScript using the onclick property",
"description": [
"You want your code to execute only once your page has finished loading. For that purpose, you can attach a JavaScript event to the document called DOMContentLoaded
. Here's the code that does this:",
"
document.addEventListener('DOMContentLoaded',function() {", "You can implement event handlers that go inside of the
});
DOMContentLoaded
function. You can implement an onclick
event handler which triggers when the user clicks on the element with id getMessage
, by adding the following code:",
"document.getElementById('getMessage').onclick=function(){};", "
DOMContentLoaded
function for the element with id of getMessage
."
],
"tests": [
{
"text":
"Your code should use the document.getElementById
method to select the getMessage
element.",
"testString":
"assert(code.match(/document\\.getElementById\\(\\s*?('|\")getMessage\\1\\s*?\\)/g), 'Your code should use the document.getElementById
method to select the getMessage
element.');"
},
{
"text": "Your code should add an onclick
event handler.",
"testString":
"assert(typeof document.getElementById('getMessage').onclick === 'function', 'Your code should add an onclick
event handler.');"
}
],
"solutions": [],
"hints": [],
"releasedOn": "Feb 17, 2017",
"challengeType": 0,
"translations": {},
"files": {
"indexhtml": {
"key": "indexhtml",
"ext": "html",
"name": "index",
"contents": [
"",
"",
"", " ", "
" ], "head": [], "tail": [] } } }, { "id": "587d7fad367417b2b2512be2", "title": "Change Text with click Events", "description": [ "When the click event happens, you can use JavaScript to update an HTML element.", "For example, when a user clicks the \"Get Message\" button, it changes the text of the element with the classmessage
to say \"Here is the message\".",
"This works by adding the following code within the click event:",
"document.getElementsByClassName('message')[0].innerHTML=\"Here is the message\";
",
"onclick
event handler to change the text inside the message
element to say \"Here is the message\"."
],
"tests": [
{
"text":
"Your code should use the document.getElementsByClassName
method to select the element with class message
and set its innerHTML
to the given string.",
"testString":
"assert(code.match(/document\\.getElementsByClassName\\(\\s*?('|\")message\\1\\s*?\\)\\[0\\]\\.innerHTML\\s*?=\\s*?('|\")Here is the message\\2/g), 'Your code should use the document.getElementsByClassName
method to select the element with class message
and set its innerHTML
to the given string.');"
}
],
"solutions": [],
"hints": [],
"releasedOn": "Feb 17, 2017",
"challengeType": 0,
"translations": {},
"files": {
"indexhtml": {
"key": "indexhtml",
"ext": "html",
"name": "index",
"contents": [
"",
"",
"", " ", "
" ], "head": [], "tail": [] } } }, { "id": "587d7fae367417b2b2512be3", "title": "Get JSON with the JavaScript XMLHttpRequest Method", "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. You'll learn how to update HTML with the data we get from APIs using a technology called AJAX.", "Most web APIs transfer data in a format called JSON. JSON stands for JavaScript Object Notation.", "JSON syntax looks very similar to JavaScript object literal notation. JSON has object properties and their current values, sandwiched between a{
and a }
.",
"These properties and their values are often referred to as \"key-value pairs\".",
"However, JSON transmitted by APIs are sent as bytes
, and your application receives it as a string
. These can be converted into JavaScript objects, but they are not JavaScript objects by default. The JSON.parse
method parses the string and constructs the JavaScript object described by it.",
"You can request the JSON from freeCodeCamp's Cat Photo API. Here's the code you can put in your click event to do this:",
"req=new XMLHttpRequest();", "Here's a review of what each piece is doing. The JavaScript
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);
};
XMLHttpRequest
object has a number of properties and methods that are used to transfer data. First, an instance of the XMLHttpRequest
object is created and saved in the req
variable.",
"Next, the open
method initializes a request - this example is requesting data from an API, therefore is a \"GET\" request. The second argument for open
is the URL of the API you are requesting data from. The third argument is a Boolean value where true
makes it an asynchronous request.",
"The send
method sends the request. Finally, the onload
event handler parses the returned data and applies the JSON.stringify
method to convert the JavaScript object into a string. This string is then inserted as the message text.",
"XMLHttpRequest
.",
"testString":
"assert(code.match(/new\\s+?XMLHttpRequest\\(\\s*?\\)/g), 'Your code should create a new XMLHttpRequest
.');"
},
{
"text":
"Your code should use the open
method to initialize a \"GET\" request to the freeCodeCamp Cat Photo API.",
"testString":
"assert(code.match(/\\.open\\(\\s*?('|\")GET\\1\\s*?,\\s*?('|\")\\/json\\/cats\\.json\\2\\s*?,\\s*?true\\s*?\\)/g), 'Your code should use the open
method to initialize a \"GET\" request to the freeCodeCamp Cat Photo API.');"
},
{
"text":
"Your code should use the send
method to send the request.",
"testString":
"assert(code.match(/\\.send\\(\\s*\\)/g), 'Your code should use the send
method to send the request.');"
},
{
"text":
"Your code should have an onload
event handler set to a function.",
"testString":
"assert(code.match(/\\.onload\\s*=\\s*function\\(\\s*?\\)\\s*?{/g), 'Your code should have an onload
event handler set to a function.');"
},
{
"text":
"Your code should use the JSON.parse
method to parse the responseText
.",
"testString":
"assert(code.match(/JSON\\.parse\\(.*\\.responseText\\)/g), 'Your code should use the JSON.parse
method to parse the responseText
.');"
},
{
"text":
"Your code should get the element with class message
and change its inner HTML to the string of JSON data.",
"testString":
"assert(code.match(/document\\.getElementsByClassName\\(\\s*?('|\")message\\1\\s*?\\)\\[0\\]\\.innerHTML\\s*?=\\s*?JSON\\.stringify\\(.+?\\)/g), 'Your code should get the element with class message
and change its inner HTML to the string of JSON data.');"
}
],
"solutions": [],
"hints": [],
"releasedOn": "Feb 17, 2017",
"challengeType": 0,
"translations": {},
"files": {
"indexhtml": {
"key": "indexhtml",
"ext": "html",
"name": "index",
"contents": [
"",
"",
"", " ", "
" ], "head": [], "tail": [] } } }, { "id": "587d7fae367417b2b2512be4", "title": "Access the JSON Data from an API", "description": [ "In the previous challenge, you saw how to get JSON data from the freeCodeCamp Cat Photo API.", "Now you'll take a closer look at the returned data to better understand the JSON format. Recall some notation in JavaScript:", "[ ] -> Square brackets represent an array", "Understanding the structure of the data that an API returns is important because it influences how you retrieve the values you need.", "On the right, click the \"Get Message\" button to load the freeCodeCamp Cat Photo API JSON into the HTML.", "The first and last character you see in the JSON data are square brackets
{ } -> Curly brackets represent an object
\" \" -> Double quotes represent a string. They are also used for key names in JSON
[ ]
. This means that the returned data is an array. The second character in the JSON data is a curly {
bracket, which starts an object. Looking closely, you can see that there are three separate objects. The JSON data is an array of three objects, where each object contains information about a cat photo.",
"You learned earlier that objects contain \"key-value pairs\" that are separated by commas. In the Cat Photo example, the first object has \"id\":0
where \"id\" is a key and 0 is its corresponding value. Similarly, there are keys for \"imageLink\", \"altText\", and \"codeNames\". Each cat photo object has these same keys, but with different values.",
"Another interesting \"key-value pair\" in the first object is \"codeNames\":[\"Juggernaut\",\"Mrs. Wallace\",\"ButterCup\"]
. Here \"codeNames\" is the key and its value is an array of three strings. It's possible to have arrays of objects as well as a key with an array as a value.",
"Remember how to access data in arrays and objects. Arrays use bracket notation to access a specific index of an item. Objects use either bracket or dot notation to access the value of a given property. Here's an example that prints the \"altText\" of the first cat photo - note that the parsed JSON data in the editor is saved in a variable called json
:",
"console.log(json[0].altText);", "
// Prints \"A white cat wearing a green helmet shaped melon on its head.\"
codeNames
array. You should use bracket and dot notation on the object (which is saved in the variable json
) to access the value."
],
"tests": [
{
"text":
"Your code should use bracket and dot notation to access the proper code name, and print \"Loki\" to the console.",
"testString":
"assert(code.match(/(?:json\\[2\\]\\.codeNames\\[1\\]|json\\[2\\]\\[('|\")codeNames\\1\\]\\[1\\])/g), 'Your code should use bracket and dot notation to access the proper code name, and print \"Loki\" to the console.');"
}
],
"solutions": [],
"hints": [],
"releasedOn": "Feb 17, 2017",
"challengeType": 0,
"translations": {},
"files": {
"indexhtml": {
"key": "indexhtml",
"ext": "html",
"name": "index",
"contents": [
"",
"",
"", " ", "
" ], "head": [], "tail": [] } } }, { "id": "587d7fae367417b2b2512be5", "title": "Convert JSON Data to HTML", "description": [ "Now that you're getting data from a JSON API, you can display it in the HTML.", "You can use aforEach
method to loop through the data since the cat photo objects are held in an array. As you get to each item, you can modify the HTML elements.",
"First, declare an html variable with var html = \"\";
.",
"Then, loop through the JSON, adding HTML to the variable that wraps the key names in strong
tags, followed by the value. When the loop is finished, you 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>\";});", "
forEach
method to loop over the JSON data and create the HTML elements to display it.",
"Here is some example JSON",
"[ { \"id\":0, \"imageLink\":\"https://s3.amazonaws.com/freecodecamp/funny-cat.jpg\", \"altText\":\"A white cat wearing a green helmet shaped melon on its head. \", \"codeNames\":[ \"Juggernaut\", \"Mrs. Wallace\", \"Buttercup\" ] }]" ], "tests": [ { "text": "Your code should store the data in the
html
variable",
"testString":
"assert(code.match(/html\\s+?(\\+=|=\\shtml\\s\\+)/g), 'Your code should store the data in the html
variable');"
},
{
"text":
"Your code should use a forEach
method to loop over the JSON data from the API.",
"testString":
"assert(code.match(/json\\.forEach/g), 'Your code should use a forEach
method to loop over the JSON data from the API.');"
},
{
"text":
"Your code should wrap the key names in strong
tags.",
"testString":
"assert(code.match(/.+<\\/strong>/g), 'Your code should wrap the key names in strong
tags.');"
}
],
"solutions": [],
"hints": [],
"releasedOn": "Feb 17, 2017",
"challengeType": 0,
"translations": {},
"files": {
"indexhtml": {
"key": "indexhtml",
"ext": "html",
"name": "index",
"contents": [
"",
"",
"", " ", "
" ], "head": [], "tail": [] } } }, { "id": "587d7fae367417b2b2512be6", "title": "Render Images from Data Sources", "description": [ "The last few challenges showed that each object in the JSON array contains animageLink
key with a value that is the URL of a cat's image.",
"When you're looping through these objects, you can 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 + \"'>\";
",
"imageLink
and altText
properties in an img
tag."
],
"tests": [
{
"text":
"You should use the imageLink
property to display the images.",
"testString":
"assert(code.match(/val\\.imageLink/g), 'You should use the imageLink
property to display the images.');"
}
],
"solutions": [],
"hints": [],
"releasedOn": "Feb 17, 2017",
"challengeType": 0,
"translations": {},
"files": {
"indexhtml": {
"key": "indexhtml",
"ext": "html",
"name": "index",
"contents": [
"",
"",
"", " ", "
" ], "head": [], "tail": [] } } }, { "id": "587d7fae367417b2b2512be7", "title": "Pre-filter JSON to Get the Data You Need", "description": [ "If you don't want to render every cat photo you get from the freeCodeCamp Cat Photo API, you can pre-filter the JSON before looping through it.", "Given that the JSON data is stored in an array, you can use thefilter
method to 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);
});
filter
the json data to remove the cat with the \"id\" value of 1."
],
"tests": [
{
"text": "Your code should use the filter
method.",
"testString":
"assert(code.match(/json\\.filter/g), 'Your code should use the filter
method.');"
}
],
"solutions": [],
"hints": [],
"releasedOn": "Feb 17, 2017",
"challengeType": 0,
"translations": {},
"files": {
"indexhtml": {
"key": "indexhtml",
"ext": "html",
"name": "index",
"contents": [
"",
"",
"", " ", "
" ], "head": [], "tail": [] } } }, { "id": "587d7faf367417b2b2512be8", "title": "Get Geolocation Data to Find A User's GPS Coordinates", "description": [ "Another cool thing you can do is access your user's current location. Every browser has a built in navigator that can give you this information.", "The navigator will get the 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 code that does this:", "if (navigator.geolocation){", "First, it checks if the
navigator.geolocation.getCurrentPosition(function(position) {
document.getElementById('data').innerHTML=\"latitude: \"+ position.coords.latitude + \"<br>longitude: \" + position.coords.longitude;
});
}
navigator.geolocation
object exists. If it does, the getCurrentPosition
method on that object is called, which initiates an asynchronous request for the user's position. If the request is successful, the callback function in the method runs. This function accesses the position
object's values for latitude and longitude using dot notation and updates the HTML.",
"script
tags to check a user's current location and insert it into the HTML."
],
"tests": [
{
"text":
"Your code should use navigator.geolocation
to access the user's current location.",
"testString":
"assert(code.match(/navigator\\.geolocation\\.getCurrentPosition/g), 'Your code should use navigator.geolocation
to access the user's current location.');"
},
{
"text":
"Your code should use position.coords.latitude
to display the user's latitudinal location.",
"testString":
"assert(code.match(/position\\.coords\\.latitude/g), 'Your code should use position.coords.latitude
to display the user's latitudinal location.');"
},
{
"text":
"Your code should use position.coords.longitude
to display the user's longitudinal location.",
"testString":
"assert(code.match(/position\\.coords\\.longitude/g), 'Your code should use position.coords.longitude
to display the user's longitudinal location.');"
},
{
"text":
"You should display the user's position within the data
div element.",
"testString":
"assert(code.match(/document\\.getElementById\\(\\s*?('|\")data\\1\\s*?\\)\\.innerHTML/g), 'You should display the user's position within the data
div element.');"
}
],
"solutions": [],
"hints": [],
"releasedOn": "Feb 17, 2017",
"challengeType": 0,
"translations": {},
"files": {
"indexhtml": {
"key": "indexhtml",
"ext": "html",
"name": "index",
"contents": [
"",
"XMLHttpRequest
method is also used to post data to a server. Here's an example:",
"req=new XMLHttpRequest();", "You've seen several of these methods before. Here the
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);
open
method initializes the request as a \"POST\" to the given URL of the external resource, and uses the true
Boolean to make it asynchronous.",
"The setRequestHeader
method sets the value of an HTTP request header, which contains information about the sender and the request. It must be called after the open
method, but before the send
method. The two parameters are the name of the header and the value to set as the body of that header.",
"Next, the onreadystatechange
event listener handles a change in the state of the request. A readyState
of 4 means the operation is complete, and a status
of 200 means it was a successful request. The document's HTML can be updated.",
"Finally, the send
method sends the request with the userName
value, which was given by the user in the input
field.",
"XMLHttpRequest
.",
"testString":
"assert(code.match(/new\\s+?XMLHttpRequest\\(\\s*?\\)/g), 'Your code should create a new XMLHttpRequest
.');"
},
{
"text":
"Your code should use the open
method to initialize a \"POST\" request to the server.",
"testString":
"assert(code.match(/\\.open\\(\\s*?('|\")POST\\1\\s*?,\\s*?url\\s*?,\\s*?true\\s*?\\)/g), 'Your code should use the open
method to initialize a \"POST\" request to the server.');"
},
{
"text":
"Your code should use the setRequestHeader
method.",
"testString":
"assert(code.match(/\\.setRequestHeader\\(\\s*?('|\")Content-Type\\1\\s*?,\\s*?('|\")text\\/plain\\2\\s*?\\)/g), 'Your code should use the setRequestHeader
method.');"
},
{
"text":
"Your code should have an onreadystatechange
event handler set to a function.",
"testString":
"assert(code.match(/\\.onreadystatechange\\s*?=/g), 'Your code should have an onreadystatechange
event handler set to a function.');"
},
{
"text":
"Your code should get the element with class message
and change its inner HTML to the responseText
.",
"testString":
"assert(code.match(/document\\.getElementsByClassName\\(\\s*?('|\")message\\1\\s*?\\)\\[0\\]\\.innerHTML\\s*?=\\s*?.+?\\.responseText/g), 'Your code should get the element with class message
and change its inner HTML to the responseText
.');"
},
{
"text": "Your code should use the send
method.",
"testString":
"assert(code.match(/\\.send\\(\\s*?userName\\s*?\\)/g), 'Your code should use the send
method.');"
}
],
"solutions": [],
"hints": [],
"releasedOn": "Feb 17, 2017",
"challengeType": 0,
"translations": {},
"files": {
"indexhtml": {
"key": "indexhtml",
"ext": "html",
"name": "index",
"contents": [
"",
"",
"", " ", " ", "
" ], "head": [], "tail": [] } } } ] }