From dd6011b2cc9b0e0ea5bc404f90f094ee5220d376 Mon Sep 17 00:00:00 2001 From: Randell Dawson <5313213+RandellDawson@users.noreply.github.com> Date: Tue, 14 May 2019 05:04:05 -0700 Subject: [PATCH] fix(curriculum): Convert blockquote elements to triple backtick syntax for Data Visualization (#35995) * fix: convert data visualization * fix: reverted to blockquote * fix: changed js to json Co-Authored-By: Oliver Eyton-Williams * fix: cleaned up code Co-Authored-By: Oliver Eyton-Williams --- .../add-axes-to-a-visualization.english.md | 10 ++++++- .../add-document-elements-with-d3.english.md | 8 +++++- .../change-styles-based-on-data.english.md | 8 +++++- ...-for-each-data-point-in-the-set.english.md | 9 ++++++- ...y-change-the-height-of-each-bar.english.md | 11 +++++++- ...et-the-coordinates-for-each-bar.english.md | 11 +++++++- ...a-domain-and-a-range-on-a-scale.english.md | 16 ++++++++++- ...defined-scale-to-place-elements.english.md | 7 ++++- .../use-dynamic-scales.english.md | 25 ++++++++++++++++- ...and-maximum-values-in-a-dataset.english.md | 17 ++++++++++-- .../work-with-data-in-d3.english.md | 16 ++++++++++- ...ccess-the-json-data-from-an-api.english.md | 7 ++++- .../convert-json-data-to-html.english.md | 27 +++++++++++++++++-- ...to-find-a-users-gps-coordinates.english.md | 10 ++++++- ...avascript-xmlhttprequest-method.english.md | 12 ++++++++- ...ript-using-the-onclick-property.english.md | 14 ++++++++-- ...avascript-xmlhttprequest-method.english.md | 16 ++++++++++- ...r-json-to-get-the-data-you-need.english.md | 8 +++++- 18 files changed, 211 insertions(+), 21 deletions(-) diff --git a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/add-axes-to-a-visualization.english.md b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/add-axes-to-a-visualization.english.md index ad3b89a3e9..543c07cacd 100644 --- a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/add-axes-to-a-visualization.english.md +++ b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/add-axes-to-a-visualization.english.md @@ -13,7 +13,15 @@ The next step is to render the axis on the SVG canvas. To do so, you can use a g Unlike rect, circle, and text, an axis is just a straight line when it's rendered. Because it is a simple shape, using g works. The last step is to apply a transform attribute to position the axis on the SVG canvas in the right place. Otherwise, the line would render along the border of SVG canvas and wouldn't be visible. SVG supports different types of transforms, but positioning an axis needs translate. When it's applied to the g element, it moves the whole group over and down by the given amounts. Here's an example: -
const xAxis = d3.axisBottom(xScale);

svg.append("g")
   .attr("transform", "translate(0, " + (h - padding) + ")")
   .call(xAxis);
+ +```js +const xAxis = d3.axisBottom(xScale); + +svg.append("g") + .attr("transform", "translate(0, " + (h - padding) + ")") + .call(xAxis); +``` + The above code places the x-axis at the bottom of the SVG canvas. Then it's passed as an argument to the call() method. The y-axis works is the same way, except the translate argument is in the form (x, 0). Because translate is a string in the attr() method above, you can use concatenation to include variable values for its arguments. diff --git a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/add-document-elements-with-d3.english.md b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/add-document-elements-with-d3.english.md index 85984c0f42..e6fdc7e326 100644 --- a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/add-document-elements-with-d3.english.md +++ b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/add-document-elements-with-d3.english.md @@ -14,7 +14,13 @@ Two other useful methods are append() and text(). The append() method takes an argument for the element you want to add to the document. It appends an HTML node to a selected item, and returns a handle to that node. The text() method either sets the text of the selected node, or gets the current text. To set the value, you pass a string as an argument inside the parentheses of the method. Here's an example that selects an unordered list, appends a list item, and adds text: -
d3.select("ul")
  .append("li")
  .text("Very important item");
+ +```js +d3.select("ul") + .append("li") + .text("Very important item"); +``` + D3 allows you to chain several methods together with periods to perform a number of actions in a row. diff --git a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/change-styles-based-on-data.english.md b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/change-styles-based-on-data.english.md index 42733ddb55..077a82b8c9 100644 --- a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/change-styles-based-on-data.english.md +++ b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/change-styles-based-on-data.english.md @@ -8,7 +8,13 @@ challengeType: 6
D3 is about visualization and presentation of data. It's likely you'll want to change the styling of elements based on the data. You can use a callback function in the style() method to change the styling for different elements. For example, you may want to color a data point blue if has a value less than 20, and red otherwise. You can use a callback function in the style() method and include the conditional logic. The callback function uses the d parameter to represent the data point: -
selection.style("color", (d) => {
  /* Logic that returns the color based on a condition */
});
+ +```js +selection.style("color", (d) => { + /* Logic that returns the color based on a condition */ +}); +``` + The style() method is not limited to setting the color - it can be used with other CSS properties as well.
diff --git a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/create-a-bar-for-each-data-point-in-the-set.english.md b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/create-a-bar-for-each-data-point-in-the-set.english.md index bd659ee887..cc13b82a84 100644 --- a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/create-a-bar-for-each-data-point-in-the-set.english.md +++ b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/create-a-bar-for-each-data-point-in-the-set.english.md @@ -8,7 +8,14 @@ challengeType: 6
The last challenge added only one rectangle to the svg element to represent a bar. Here, you'll combine what you've learned so far about data(), enter(), and SVG shapes to create and append a rectangle for each data point in dataset. A previous challenge showed the format for how to create and append a div for each item in dataset: -
d3.select("body").selectAll("div")
  .data(dataset)
  .enter()
  .append("div")
+ +```js +d3.select("body").selectAll("div") + .data(dataset) + .enter() + .append("div") +``` + There are a few differences working with rect elements instead of divs. The rects must be appended to an svg element, not directly to the body. Also, you need to tell D3 where to place each rect within the svg area. The bar placement will be covered in the next challenge.
diff --git a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/dynamically-change-the-height-of-each-bar.english.md b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/dynamically-change-the-height-of-each-bar.english.md index 44953d2e7d..b881c5342f 100644 --- a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/dynamically-change-the-height-of-each-bar.english.md +++ b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/dynamically-change-the-height-of-each-bar.english.md @@ -7,7 +7,16 @@ challengeType: 6 ## Description
The height of each bar can be set to the value of the data point in the array, similar to how the x value was set dynamically. -
selection.attr("property", (d, i) => {
  /*
  * d is the data point value
  * i is the index of the data point in the array
  */
})
+ +```js +selection.attr("property", (d, i) => { + /* + * d is the data point value + * i is the index of the data point in the array + */ +}) +``` +
## Instructions diff --git a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/dynamically-set-the-coordinates-for-each-bar.english.md b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/dynamically-set-the-coordinates-for-each-bar.english.md index 753ad4d45d..89ed4ba479 100644 --- a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/dynamically-set-the-coordinates-for-each-bar.english.md +++ b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/dynamically-set-the-coordinates-for-each-bar.english.md @@ -10,7 +10,16 @@ The last challenge created and appended a rectangle to the svg elem The placement of a rectangle is handled by the x and y attributes. They tell D3 where to start drawing the shape in the svg area. The last challenge set them each to 0, so every bar was placed in the upper-left corner. For a bar chart, all of the bars should sit on the same vertical level, which means the y value stays the same (at 0) for all bars. The x value, however, needs to change as you add new bars. Remember that larger x values push items farther to the right. As you go through the array elements in dataset, the x value should increase. The attr() method in D3 accepts a callback function to dynamically set that attribute. The callback function takes two arguments, one for the data point itself (usually d) and one for the index of the data point in the array. The second argument for the index is optional. Here's the format: -
selection.attr("property", (d, i) => {
  /*
  * d is the data point value
  * i is the index of the data point in the array
  */
})
+ +```js +selection.attr("property", (d, i) => { + /* + * d is the data point value + * i is the index of the data point in the array + */ +}) +``` + It's important to note that you do NOT need to write a for loop or use forEach() to iterate over the items in the data set. Recall that the data() method parses the data set, and any method that's chained after data() is run once for each item in the data set. diff --git a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/set-a-domain-and-a-range-on-a-scale.english.md b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/set-a-domain-and-a-range-on-a-scale.english.md index b326b69900..cf3b8a53ec 100644 --- a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/set-a-domain-and-a-range-on-a-scale.english.md +++ b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/set-a-domain-and-a-range-on-a-scale.english.md @@ -10,7 +10,21 @@ By default, scales use the identity relationship - the input value maps to the o Say a data set has values ranging from 50 to 480. This is the input information for a scale, and is also known as the domain. You want to map those points along the x axis on the SVG canvas, between 10 units and 500 units. This is the output information, which is also known as the range. The domain() and range() methods set these values for the scale. Both methods take an array of at least two elements as an argument. Here's an example: -
// Set a domain
// The domain covers the set of input values
scale.domain([50, 480]);
// Set a range
// The range covers the set of output values
scale.range([10, 500]);
scale(50) // Returns 10
scale(480) // Returns 500
scale(325) // Returns 323.37
scale(750) // Returns 807.67
d3.scaleLinear()
+ +```js +// Set a domain +// The domain covers the set of input values +scale.domain([50, 480]); +// Set a range +// The range covers the set of output values +scale.range([10, 500]); +scale(50) // Returns 10 +scale(480) // Returns 500 +scale(325) // Returns 323.37 +scale(750) // Returns 807.67 +d3.scaleLinear() +``` + Notice that the scale uses the linear relationship between the domain and range values to figure out what the output should be for a given number. The minimum value in the domain (50) maps to the minimum value (10) in the range. diff --git a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/use-a-pre-defined-scale-to-place-elements.english.md b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/use-a-pre-defined-scale-to-place-elements.english.md index 818519c8aa..a24945733b 100644 --- a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/use-a-pre-defined-scale-to-place-elements.english.md +++ b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/use-a-pre-defined-scale-to-place-elements.english.md @@ -8,7 +8,12 @@ challengeType: 6
With the scales set up, it's time to map the scatter plot again. The scales are like processing functions that turn the x and y raw data into values that fit and render correctly on the SVG canvas. They keep the data within the screen's plotting area. You set the coordinate attribute values for an SVG shape with the scaling function. This includes x and y attributes for rect or text elements, or cx and cy for circles. Here's an example: -
shape
  .attr("x", (d) => xScale(d[0]))
+ +```js +shape + .attr("x", (d) => xScale(d[0])) +``` + Scales set shape coordinate attributes to place the data points onto the SVG canvas. You don't need to apply scales when you display the actual data value, for example, in the text() method for a tooltip or label.
diff --git a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/use-dynamic-scales.english.md b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/use-dynamic-scales.english.md index a294c22026..b6838ba10b 100644 --- a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/use-dynamic-scales.english.md +++ b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/use-dynamic-scales.english.md @@ -10,7 +10,30 @@ The D3 min() and max() methods are useful to help set Given a complex data set, one priority is to set the scale so the visualization fits the SVG container's width and height. You want all the data plotted inside the SVG canvas so it's visible on the web page. The example below sets the x-axis scale for scatter plot data. The domain() method passes information to the scale about the raw data values for the plot. The range() method gives it information about the actual space on the web page for the visualization. In the example, the domain goes from 0 to the maximum in the set. It uses the max() method with a callback function based on the x values in the arrays. The range uses the SVG canvas' width (w), but it includes some padding, too. This puts space between the scatter plot dots and the edge of the SVG canvas. -
const dataset = [
  [ 34, 78 ],
  [ 109, 280 ],
  [ 310, 120 ],
  [ 79, 411 ],
  [ 420, 220 ],
  [ 233, 145 ],
  [ 333, 96 ],
  [ 222, 333 ],
  [ 78, 320 ],
  [ 21, 123 ]
];
const w = 500;
const h = 500;

// Padding between the SVG canvas boundary and the plot
const padding = 30;
const xScale = d3.scaleLinear()
  .domain([0, d3.max(dataset, (d) => d[0])])
  .range([padding, w - padding]);
+ +```js +const dataset = [ + [ 34, 78 ], + [ 109, 280 ], + [ 310, 120 ], + [ 79, 411 ], + [ 420, 220 ], + [ 233, 145 ], + [ 333, 96 ], + [ 222, 333 ], + [ 78, 320 ], + [ 21, 123 ] +]; +const w = 500; +const h = 500; + +// Padding between the SVG canvas boundary and the plot +const padding = 30; +const xScale = d3.scaleLinear() + .domain([0, d3.max(dataset, (d) => d[0])]) + .range([padding, w - padding]); +``` + The padding may be confusing at first. Picture the x-axis as a horizontal line from 0 to 500 (the width value for the SVG canvas). Including the padding in the range() method forces the plot to start at 30 along that line (instead of 0), and end at 470 (instead of 500). diff --git a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/use-the-d3.max-and-d3.min-functions-to-find-minimum-and-maximum-values-in-a-dataset.english.md b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/use-the-d3.max-and-d3.min-functions-to-find-minimum-and-maximum-values-in-a-dataset.english.md index b5966d8aaa..b4ed5bb519 100644 --- a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/use-the-d3.max-and-d3.min-functions-to-find-minimum-and-maximum-values-in-a-dataset.english.md +++ b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/use-the-d3.max-and-d3.min-functions-to-find-minimum-and-maximum-values-in-a-dataset.english.md @@ -9,11 +9,24 @@ challengeType: 6 The D3 methods domain() and range() set that information for your scale based on the data. There are a couple methods to make that easier. Often when you set the domain, you'll want to use the minimum and maximum values within the data set. Trying to find these values manually, especially in a large data set, may cause errors. D3 has two methods - min() and max() to return this information. Here's an example: -
const exampleData = [34, 234, 73, 90, 6, 52];
d3.min(exampleData) // Returns 6
d3.max(exampleData) // Returns 234
+ +```js +const exampleData = [34, 234, 73, 90, 6, 52]; +d3.min(exampleData) // Returns 6 +d3.max(exampleData) // Returns 234 +``` + A dataset may have nested arrays, like the [x, y] coordinate pairs that were in the scatter plot example. In that case, you need to tell D3 how to calculate the maximum and minimum. Fortunately, both the min() and max() methods take a callback function. In this example, the callback function's argument d is for the current inner array. The callback needs to return the element from the inner array (the x or y value) over which you want to compute the maximum or minimum. Here's an example for how to find the min and max values with an array of arrays: -
const locationData = [[1, 7],[6, 3],[8, 3]];
// Returns the smallest number out of the first elements
const minX = d3.min(locationData, (d) => d[0]);
// minX compared 1, 6, and 8 and is set to 1
+ +```js +const locationData = [[1, 7],[6, 3],[8, 3]]; +// Returns the smallest number out of the first elements +const minX = d3.min(locationData, (d) => d[0]); +// minX compared 1, 6, and 8 and is set to 1 +``` + ## Instructions diff --git a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/work-with-data-in-d3.english.md b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/work-with-data-in-d3.english.md index 458d118202..57d9ace390 100644 --- a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/work-with-data-in-d3.english.md +++ b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/work-with-data-in-d3.english.md @@ -11,7 +11,21 @@ The first step is to make D3 aware of the data. The data() method i A common workflow pattern is to create a new element in the document for each piece of data in the set. D3 has the enter() method for this purpose. When enter() is combined with the data() method, it looks at the selected elements from the page and compares them to the number of data items in the set. If there are fewer elements than data items, it creates the missing elements. Here is an example that selects a ul element and creates a new list item based on the number of entries in the array: -
<body>
  <ul></ul>
  <script>
    const dataset = ["a", "b", "c"];
    d3.select("ul").selectAll("li")
      .data(dataset)
      .enter()
      .append("li")
      .text("New item");
  </script>
</body>
+ +```html + + + + +``` + It may seem confusing to select elements that don't exist yet. This code is telling D3 to first select the ul on the page. Next, select all list items, which returns an empty selection. Then the data() method reviews the dataset and runs the following code three times, once for each item in the array. The enter() method sees there are no li elements on the page, but it needs 3 (one for each piece of data in dataset). New li elements are appended to the ul and have the text "New item". diff --git a/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/access-the-json-data-from-an-api.english.md b/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/access-the-json-data-from-an-api.english.md index 74bf29fdd4..b79d1e4398 100644 --- a/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/access-the-json-data-from-an-api.english.md +++ b/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/access-the-json-data-from-an-api.english.md @@ -15,7 +15,12 @@ The first and last character you see in the JSON data are square brackets 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."
+ +```js +console.log(json[0].altText); +// Prints "A white cat wearing a green helmet shaped melon on its head." +``` + ## Instructions diff --git a/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/convert-json-data-to-html.english.md b/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/convert-json-data-to-html.english.md index ca9714f98b..58ee2c32f2 100644 --- a/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/convert-json-data-to-html.english.md +++ b/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/convert-json-data-to-html.english.md @@ -11,14 +11,37 @@ You can use a forEach method to loop through the data since the cat 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>";
});
+ +```js +json.forEach(function(val) { + var keys = Object.keys(val); + html += "
"; + keys.forEach(function(key) { + html += "" + key + ": " + val[key] + "
"; + }); + html += "

"; +}); +``` + ## Instructions
Add a 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"
    ]
  }
]
+ +```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 diff --git a/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/get-geolocation-data-to-find-a-users-gps-coordinates.english.md b/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/get-geolocation-data-to-find-a-users-gps-coordinates.english.md index 7b33b5d2e7..82eb6e7070 100644 --- a/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/get-geolocation-data-to-find-a-users-gps-coordinates.english.md +++ b/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/get-geolocation-data-to-find-a-users-gps-coordinates.english.md @@ -11,7 +11,15 @@ 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){
  navigator.geolocation.getCurrentPosition(function(position) {
    document.getElementById('data').innerHTML="latitude: "+ position.coords.latitude + "<br>longitude: " + position.coords.longitude;
  });
}
+ +```js +if (navigator.geolocation){ + navigator.geolocation.getCurrentPosition(function(position) { + document.getElementById('data').innerHTML="latitude: " + position.coords.latitude + "
longitude: " + position.coords.longitude; + }); +} +``` + First, it checks if the 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. diff --git a/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/get-json-with-the-javascript-xmlhttprequest-method.english.md b/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/get-json-with-the-javascript-xmlhttprequest-method.english.md index 6d7f42a309..550dd7f93a 100644 --- a/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/get-json-with-the-javascript-xmlhttprequest-method.english.md +++ b/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/get-json-with-the-javascript-xmlhttprequest-method.english.md @@ -13,7 +13,17 @@ JSON syntax looks very similar to JavaScript object literal notation. JSON has o 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();
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);
};
+ +```js +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); +}; +``` + Here's a review of what each piece is doing. The JavaScript 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. diff --git a/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/handle-click-events-with-javascript-using-the-onclick-property.english.md b/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/handle-click-events-with-javascript-using-the-onclick-property.english.md index 799f966428..e24b6beb13 100644 --- a/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/handle-click-events-with-javascript-using-the-onclick-property.english.md +++ b/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/handle-click-events-with-javascript-using-the-onclick-property.english.md @@ -7,9 +7,19 @@ challengeType: 6 ## 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() {

});
+ +```js +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(){};
+ +```js +document.getElementById('getMessage').onclick=function(){}; +``` +
## Instructions diff --git a/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/post-data-with-the-javascript-xmlhttprequest-method.english.md b/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/post-data-with-the-javascript-xmlhttprequest-method.english.md index 9f024ae0ea..54cc973b37 100644 --- a/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/post-data-with-the-javascript-xmlhttprequest-method.english.md +++ b/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/post-data-with-the-javascript-xmlhttprequest-method.english.md @@ -8,7 +8,21 @@ challengeType: 6
In the previous examples, you received data from an external resource. You can also send data to an external resource, as long as that resource supports AJAX requests and you know the URL. JavaScript's XMLHttpRequest method is also used to post data to a server. Here's an example: -
const xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
xhr.onreadystatechange = function () {
  if (xhr.readyState === 4 && xhr.status === 201){
    const serverResponse = JSON.parse(xhr.response);
    document.getElementsByClassName('message')[0].textContent = serverResponse.userName + serverResponse.suffix;
  }
};
const body = JSON.stringify({ userName: userName, suffix: ' loves cats!' });
xhr.send(body);
+ +```js +const xhr = new XMLHttpRequest(); +xhr.open('POST', url, true); +xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8'); +xhr.onreadystatechange = function () { + if (xhr.readyState === 4 && xhr.status === 201){ + const serverResponse = JSON.parse(xhr.response); + document.getElementsByClassName('message')[0].textContent = serverResponse.userName + serverResponse.suffix; + } +}; +const body = JSON.stringify({ userName: userName, suffix: ' loves cats!' }); +xhr.send(body); +``` + You've seen several of these methods before. Here the 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 201 means it was a successful request. The document's HTML can be updated. diff --git a/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/pre-filter-json-to-get-the-data-you-need.english.md b/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/pre-filter-json-to-get-the-data-you-need.english.md index 7e52940801..989111adb0 100644 --- a/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/pre-filter-json-to-get-the-data-you-need.english.md +++ b/curriculum/challenges/english/04-data-visualization/json-apis-and-ajax/pre-filter-json-to-get-the-data-you-need.english.md @@ -9,7 +9,13 @@ challengeType: 6 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 the filter 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);
});
+ +```js +json = json.filter(function(val) { + return (val.id !== 1); +}); +``` +
## Instructions