MediaWiki API result

This is the HTML representation of the JSON format. HTML is good for debugging, but is unsuitable for application use.

Specify the format parameter to change the output format. To see the non-HTML representation of the JSON format, set format=json.

See the complete documentation, or the API help for more information.

{
    "batchcomplete": "",
    "continue": {
        "gapcontinue": "Ruby",
        "continue": "gapcontinue||"
    },
    "warnings": {
        "main": {
            "*": "Subscribe to the mediawiki-api-announce mailing list at <https://lists.wikimedia.org/postorius/lists/mediawiki-api-announce.lists.wikimedia.org/> for notice of API deprecations and breaking changes."
        },
        "revisions": {
            "*": "Because \"rvslots\" was not specified, a legacy format has been used for the output. This format is deprecated, and in the future the new format will always be used."
        }
    },
    "query": {
        "pages": {
            "1067": {
                "pageid": 1067,
                "ns": 0,
                "title": "React",
                "revisions": [
                    {
                        "contentformat": "text/x-wiki",
                        "contentmodel": "wikitext",
                        "*": "Notes from '''Learning React, 2nd Edition''' by Porcello & Banks and other sources\n\n= Installation =\n\n<source lang=\"console\">\n// initialize a nodejs project (creates package.json)\n$ npm init -y\n\n// package manager \n$ npm install yarn\n\n$ yarn install packagename\n\n$ yarn remove packagename\n</source>\n\n= JavaScript =\n\n[http://kangax.github.io/compat-table/esnext/ Kangax compatibility table]\n\n== Three ways to declare variables are == \n\n# const\n# var\n# let\n\n\n== Template string ==\n\n<source lang=\"js\">\nconsole.log(`${lastName}, ${firstName} ${middleName}`);\n\ndocument.body.innerHTML = `\n<section>\n  <header>\n      <h1>The React Blog</h1>\n  </header>\n  <article>\n      <h2>${article.title}</h2>\n      ${article.body}\n  </article>\n  <footer>\n      <p>copyright ${new Date().getYear()} | The React Blog</p>\n  </footer>\n</section>\n`;\n</source>\n\n\n== Function declaration vs function expression ==\n\ndeclarations are hoisted\n\n<source lang=\"js\">\nconst f = function() {\n};\n</source>\n\n\n== Arrow functions ==\n\n<source lang=\"js\">\nconst lordify = function(firstName) {\n  return `${firstName} of Canterbury`;\n};\n\n// equals\n\nconst lordify = firstName => `${firstName} of Canterbury`;\n</source>\n\n\n== Returning an object ==\n\n'''DON'T FORGET PARENTHESES!'''\n\n<source lang=\"js\">\nconst person = (firstName, lastName) => ({\n  first: firstName,\n  last: lastName\n});\n\nconsole.log(person(\"Flad\", \"Hanson\"));\n</source>\n\n\n== Arrow functions and scope ==\n\nReference\n\n* [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions Arrow functions]\n* [https://www.codementor.io/dariogarciamoya/understanding-this-in-javascript-with-arrow-functions-gcpjwfyuc Understanding \"this\" in javascript with arrow functions]\n\n\n\n<source lang=\"js\">\nconst tahoe = {\n  mountains: [\"Freel\", \"Rose\", \"Tallac\", \"Rubicon\", \"Silver\"],\n  print: function(delay = 1000) {\n    setTimeout(function() {\n      console.log(this.mountains.join(\", \"));\n    }, delay);\n  }\n};\n\ntahoe.print(); // Uncaught TypeError: Cannot read property 'join' of undefined\n\nconsole.log(this); // Window {}\n</source>\n\nTo solve this problem:\n\n<source lang=\"js\">\nconst tahoe = {\n  mountains: [\"Freel\", \"Rose\", \"Tallac\", \"Rubicon\", \"Silver\"],\n  print: function(delay = 1000) {\n    setTimeout(() => {\n      console.log(this.mountains.join(\", \"));\n    }, delay);\n  }\n};\n\ntahoe.print(); // Freel, Rose, Tallac, Rubicon, Silver\n</source>\n\n== Destructing objects ==\n\n<source lang=\"js\">\nconst sandwich = {\n  bread: \"dutch crunch\",\n  meat: \"tuna\",\n  cheese: \"swiss\",\n  toppings: [\"lettuce\", \"tomato\", \"mustard\"]\n};\n\nconst { bread, meat } = sandwich;\n\nconsole.log(bread, meat); // dutch crunch tuna\n</source>\n\n\n<source lang=\"js\">\nconst sandwich = {\n  bread: \"dutch crunch\",\n  meat: \"tuna\",\n  cheese: \"swiss\",\n  toppings: [\"lettuce\", \"tomato\", \"mustard\"]\n};\n\nlet { bread, meat } = sandwich;\n\nbread = \"garlic\";\nmeat = \"turkey\";\n\nconsole.log(bread); // garlic\nconsole.log(meat); // turkey\n\nconsole.log(sandwich.bread, sandwich.meat); // dutch crunch tuna\n</source>\n\n\ndestructuring parameter\n\n<source lang=\"js\">\nconst lordify = ({ firstname }) => {\n  console.log(`${firstname} of Canterbury`);\n};\n\nconst regularPerson = {\n  firstname: \"Bill\",\n  lastname: \"Wilson\"\n};\n\nlordify(regularPerson); // Bill of Canterbury\n</source>\n\n\n<source lang=\"js\">\nconst regularPerson = {\n  firstname: \"Bill\",\n  lastname: \"Wilson\",\n  spouse: {\n    firstname: \"Phil\",\n    lastname: \"Wilson\"\n  }\n};\n\nconst lordify = ({ spouse: { firstname } }) => {\n  console.log(`${firstname} of Canterbury`);\n};\n\nlordify(regularPerson); // Phil of Canterbury\n</source>\n\n\n== Destructuring arrays ==\n\n<source lang=\"js\">\nconst [firstAnimal] = [\"Horse\", \"Mouse\", \"Cat\"];\n\nconsole.log(firstAnimal); // Horse\n\nconst [, , thirdAnimal] = [\"Horse\", \"Mouse\", \"Cat\"];\n\nconsole.log(thirdAnimal); // Cat\n</source>\n\n\n== Object literal enhancement ==\n\n<source lang=\"js\">\nconst name = \"Tallac\";\nconst elevation = 9738;\n\nconst funHike = { name, elevation };\n\nconsole.log(funHike); // {name: \"Tallac\", elevation: 9738}\n</source>\n\n<source lang=\"js\">\nconst name = \"Tallac\";\nconst elevation = 9738;\nconst print = function() {\n  console.log(`Mt. ${this.name} is ${this.elevation} feet tall`);\n};\n\nconst funHike = { name, elevation, print };\n\nfunHike.print(); // Mt. Tallac is 9738 feet tall\n</source>\n\n\n== old vs. new: object syntax ==\n\n<source lang=\"js\">\n// Old\nvar skier = {\n  name: name,\n  sound: sound,\n  powderYell: function() {\n    var yell = this.sound.toUpperCase();\n    console.log(`${yell} ${yell} ${yell}!!!`);\n  },\n  speed: function(mph) {\n    this.speed = mph;\n    console.log(\"speed:\", mph);\n  }\n};\n\n// New\nconst skier = {\n  name,\n  sound,\n  powderYell() {\n    let yell = this.sound.toUpperCase();\n    console.log(`${yell} ${yell} ${yell}!!!`);\n  },\n  speed(mph) {\n    this.speed = mph;\n    console.log(\"speed:\", mph);\n  }\n};\n</source>\n\n\n== Spread operator ==\n\nReference: [https://github.com/tc39/proposal-object-rest-spread Object Rest/Spread Properties for ECMAScript]\n\n<source lang=\"js\">\nconst peaks = [\"Tallac\", \"Ralston\", \"Rose\"];\nconst canyons = [\"Ward\", \"Blackwood\"];\nconst tahoe = [...peaks, ...canyons];\n\nconsole.log(tahoe.join(\", \")); // Tallac, Ralston, Rose, Ward, Blackwood\n</source>\n\nGetting last element:\n\n<source lang=\"js\">\nconst peaks = [\"Tallac\", \"Ralston\", \"Rose\"];\nconst [last] = peaks.reverse();\n\nconsole.log(last); // Rose\nconsole.log(peaks.join(\", \")); // Rose, Ralston, Tallac\n</source>\n\nGetting the rest of elements:\n\n<source lang=\"js\">\nconst lakes = [\"Donner\", \"Marlette\", \"Fallen Leaf\", \"Cascade\"];\n\nconst [first, ...others] = lakes;\n\nconsole.log(others.join(\", \")); // Marlette, Fallen Leaf, Cascade\n</source>\n\nfunction parameters:\n\n<source lang=\"js\">\nfunction directions(...args) {\n  let [start, ...remaining] = args;\n  let [finish, ...stops] = remaining.reverse();\n\n  console.log(`drive through ${args.length} towns`);\n  console.log(`start in ${start}`);\n  console.log(`the destination is ${finish}`);\n  console.log(`stopping ${stops.length} times in between`);\n}\n\ndirections(\"Truckee\", \"Tahoe City\", \"Sunnyside\", \"Homewood\", \"Tahoma\");\n</source>\n\ncombining objects:\n\n<source lang=\"js\">\nconst morning = {\n  breakfast: \"oatmeal\",\n  lunch: \"peanut butter and jelly\"\n};\n\nconst dinner = \"mac and cheese\";\n\nconst backpackingMeals = {\n  ...morning,\n  dinner\n};\n\nconsole.log(backpackingMeals);\n\n// {\n//   breakfast: \"oatmeal\",\n//   lunch: \"peanut butter and jelly\",\n//   dinner: \"mac and cheese\"\n// }\n</source>\n\n== Asynchronous requests ==\n\n=== Simple promises with fetch ===\n\n<source lang=\"js\">\nfetch(\"https://api.randomuser.me/?nat=US&results=1\")\n  .then(res => res.json())\n  .then(json => json.results)\n  .then(console.log)\n  .catch(console.error);\n</source>\n\n\n=== Async/Await ===\n\n<source lang=\"js\">\nconst getFakePerson = async () => {\n  try {\n    let res = await fetch(\"https://api.randomuser.me/?nat=US&results=1\");\n    let { results } = res.json();\n    console.log(results);\n  } catch (error) {\n    console.error(error);\n  }\n};\n\ngetFakePerson();\n</source>\n\n\n=== Building Promises ===\n\n<source lang=\"js\">\nconst getPeople = count =>\n  new Promise((resolves, rejects) => {\n    const api = `https://api.randomuser.me/?nat=US&results=${count}`;\n    const request = new XMLHttpRequest();\n    request.open(\"GET\", api);\n    request.onload = () =>\n      request.status === 200\n        ? resolves(JSON.parse(request.response).results)\n        : reject(Error(request.statusText));\n    request.onerror = err => rejects(err);\n    request.send();\n  });\n\ngetPeople(5)\n  .then(members => console.log(members))\n  .catch(error => console.error(`getPeople failed: ${error.message}`))\n);\n</source>\n\n\n== Classes ==\n\n=== prototypical inheritance ===\n\n<source lang=\"js\">\nfunction Vacation(destination, length) {\n  this.destination = destination;\n  this.length = length;\n}\n\nVacation.prototype.print = function() {\n  console.log(this.destination + \" | \" + this.length + \" days\");\n};\n\nconst maui = new Vacation(\"Maui\", 7);\n\nmaui.print(); // Maui | 7 days\n</source>\n\n=== ES2015 way of declaring class ===\n\n<source lang=\"js\">\nclass Vacation {\n  constructor(destination, length) {\n    this.destination = destination;\n    this.length = length;\n  }\n\n  print() {\n    console.log(`${this.destination} will take ${this.length} days.`);\n  }\n}\n\nconst trip = new Vacation(\"Santiago, Chile\", 7);\n\ntrip.print(); // Chile will take 7 days.\n</source>\n\nSimple inheritance\n\n<source lang=\"js\">\nclass Expedition extends Vacation {\n  constructor(destination, length, gear) {\n    super(destination, length);\n    this.gear = gear;\n  }\n\n  print() {\n    super.print();\n    console.log(`Bring your ${this.gear.join(\" and your \")}`);\n  }\n}\n\nconst trip = new Expedition(\"Mt. Whitney\", 3, [\n  \"sunglasses\",\n  \"prayer flags\",\n  \"camera\"\n]);\n\ntrip.print();\n\n// Mt. Whitney will take 3 days.\n// Bring your sunglasses and your prayer flags and your camera\n</source>\n\n\n== ES6 Modules ==\n\nA module is a peice of reusable code that can easily be incorporated into other JavaScript files without causing variable collisions.\n\nIn text-helpers.js, two functions are exported:\n\n<source lang=\"js\">\nexport const print(message) => log(message, new Date())\n\nexport const log(message, timestamp) =>\n  console.log(`${timestamp.toString()}: ${message}`)\n</source>\n\nExporting only one variable from a module using ''export default''\n\n<source lang=\"js\">\nexport default new Expedition(\"Mt. Freel\", 2, ['water\",\"snack\"]);\n</source>\n\n=== Consuming using the '''import''' command ===\n\n<source lang=\"js\">\nimport { print, log } from \"./text-helpers\";\nimport freel from \"./mt-freel\";\n\nprint(\"printing a message\");\nlog(\"logging a message\");\n\nfreel.print();\n</source>\n\nscoping under different name:\n\n<source lang=\"js\">\nimport { print as p, log as l } from \"./text-helpers\";\n\np(\"printing a message\");\nl(\"logging a message\");\n</source>\n\nimport everything\n\n<source lang=\"js\">\nimport * as fns from './text-helpers`\n</source>\n\n\n=== CommonJS ===\n\nthe module pattern that is supported by all versions of Node, \"Modules\"\n\ne.g.\n\n<source lang=\"js\">\nconst print(message) => log(message, new Date())\n\nconst log(message, timestamp) =>\nconsole.log(`${timestamp.toString()}: ${message}`}\n\nmodule.exports = {print, log}\n</source>\n\nCommonJS does not support an '''import''' statement; modules are mported with the '''require''' function\n\n<source lang=\"js\">\nconst { log, print } = require(\"./txt-helpers\");\n</source>\n\n\n= Functional Programming with JavaScript =\n\n== What it means to be functional ==\n\nJavaScript functions are first-class citizens -- they can do the same things that variables can do.  Functions can represent data. e.g.\n\n<source lang=\"js\">\nvar log = function(msg) {\n  console.log(msg);\n}\n\nlog(\"In JS functions are variables\");\n\n// equivalent to\n\nconst log = msg => { console.log(msg); };\n</source>\n\nwe can add them to objects:\n\n<source lang=\"js\">\nconst obj = {\n  msg: \"they can be added to objects like variables\",\n  log(msg) { console.log(msg); }\n};\n\nobj.log(obj.msg);\n</source>\n\nadd them to arrays:\n\n<source lang=\"js\">\nconst messages = [\n  \"They can be inserted into arrays\",\n  message => console.log(message),\n  \"like variables\",\n  message => console.log(message)\n];\n\nmessages[1](messages[0]); // They can be inserted into arrays\nmessages[3](messages[2]); // like variables\n</source>\n\nsend to other functions as arguments:\n\n<source lang=\"js\">\nconst insideFn = logger => {\n  logger(\"They can be sent to other functions as arguments\");\n};\n\ninsideFn(message => console.log(message));\n\n// They can be sent to other functions as arguments\n</source>\n\nreturned from other functions:\n\n<source lang=\"js\">\nconst createScream = function(logger) {\n  return function(message) {\n    logger(message.toUpperCase() + \"!!!\");\n  };\n};\n\nconst scream = createScream(message => console.log(message));\n\nscream(\"functions can be returned from other functions\");\nscream(\"createScream returns a function\");\nscream(\"scream invokes that returned function\");\n\n// FUNCTIONS CAN BE RETURNED FROM OTHER FUNCTIONS!!!\n// CREATESCREAM RETURNS A FUNCTION!!!\n// SCREAM INVOKES THAT RETURNED FUNCTION!!!\n\n// equivalent to (using arrows)\n\nconst createScream = logger => message => {\n  logger(message.toUpperCase() + \"!!!\");\n};\n\n// when more than one arrows exist, there's a higher-order function\n</source>\n\n</source>\n\n\n== Imperative versus declarative ==\n\n<source lang=\"js\">\n// making a string URL friendly\n\n\n// IMPERATIVE way\n\nconst string = \"Restaurants in Hanalei\";\nconst urlFriendly = \"\";\n\nfor (var i = 0; i < string.length; i++) {\n  if (string[i] === \" \") {\n    urlFriendly += \"-\";\n  } else {\n    urlFriendly += string[i];\n  }\n}\n\nconsole.log(urlFriendly); // \"Restaurants-in-Hanalei\"\n\n\n// DECLARATIVE way\n\nconst string = \"Restaurants in Hanalei\";\nconst urlFriendly = string.replace(/ /g, \"-\");\n\nconsole.log(urlFriendly);\n</source>\n\nReference: [http://c2.com/cgi/wiki?DeclarativeProgramming Declarative Programming wiki -- more about d/p paradigm]\n\nDeclaring DOM example\n\n<source lang=\"js\">\n// imperative approach\n\nconst target = document.getElementById(\"target\");\nconst wrapper = document.createElement(\"div\");\nconst headline = document.createElement(\"h1\");\n\nwrapper.id = \"welcome\";\nheadline.innerText = \"Hello World\";\n\nwrapper.appendChild(headline);\ntarget.appendChild(wrapper);\n\n\n// declarative approach using a React component\n\nconst { render } = ReactDOM;\n\nconst Welcome = () => (\n  <div id=\"welcome\">\n    <h1>Hello World</h1>\n  </div>\n);\n\nrender(<Welcome />, document.getElementById(\"target\"));\n</source>\n\n\n== Functional concepts ==\n\ncore concepts: immutability, purity, data transformation, higher-order functions, and recursion\n\n=== Immutability ===\n\ndata mutation\n\n<source lang=\"js\">\nlet color_lawn = {\n  title: \"lawn\",\n  color: \"#00ff00\",\n  rating: 0\n};\n\nfunction rateColor(color, rating) {\n  color.rating = rating;\n  return color;\n}\n\nconsole.log(rateColor(color_lawn, 5).rating); // 5\nconsole.log(color_lawn.rating); // 5\n</source>\n\nin JS, function arguments are references to the actual data; we can rewrite so it does not harm the original data\n\n<source lang=\"js\">\nconst rateColor = function(color, rating) {\n  return Object.assign({}, color, { rating: rating }); // take a blank object, copy copy to that object, and overwrite rating on the copy\n};\n\nconsole.log(rateColor(color_lawn, 5).rating); // 5\nconsole.log(color_lawn.rating); // 4\n\n// use the spread operator to copy the color into a new object and then overwrite its rating:\n// equivalent to\n\nconst rateColor = (color, rating) => ({\n  ...color,\n  rating\n});\n</source>\n\nadding elements to an array\n\n<source lang=\"js\">\nlet list = [{ title: \"Rad Red\" }, { title: \"Lawn\" }, { title: \"Party Pink\" }];\n\nconst addColor = function(title, colors) {\n  colors.push({ title: title });\n  return colors;\n};\n\nconsole.log(addColor(\"Glam Green\", list).length); // 4\nconsole.log(list.length); // 4\n\n// use Array.concat to keep immutable\n\nconst addColor = (title, array) => array.concat({ title });\n\nconsole.log(addColor(\"Glam Green\", list).length); // 4\nconsole.log(list.length); // 3\n\n// equivalent using spread operator\n// copies the original list to a new array and then adds a new object containing the color's title to that copy.\n\nconst addColor = (title, list) => [...list, { title }];\n</source>\n\n\n=== Pure Functions ===\n\nfunction that returns a value that is computed based on its argument; treats arguments as immutable data, so nothing else is changed about the application\n\ne.g. impure function\n<source lang=\"js\">\nconst frederick = {\n  name: \"Frederick Douglass\",\n  canRead: false,\n  canWrite: false\n};\n\nfunction selfEducate() {\n  frederick.canRead = true;\n  frederick.canWrite = true;\n  return frederick;\n}\n\nselfEducate();\nconsole.log(frederick);\n\n// {name: \"Frederick Douglass\", canRead: true, canWrite: true}\n\n// still the same result\n\nconst selfEducate = person => {\n  person.canRead = true;\n  person.canWrite = true;\n  return person;\n};\n\nconsole.log(selfEducate(frederick));\nconsole.log(frederick);\n\n// {name: \"Frederick Douglass\", canRead: true, canWrite: true}\n// {name: \"Frederick Douglass\", canRead: true, canWrite: true}\n</source>\n\n\n\nhave this function take an argument (now pure)\n\n<source lang=\"js\">\nconst frederick = {\n  name: \"Frederick Douglass\",\n  canRead: false,\n  canWrite: false\n};\n\nconst selfEducate = person => ({\n  ...person,\n  canRead: true,\n  canWrite: true\n});\n\nconsole.log(selfEducate(frederick));\nconsole.log(frederick);\n\n// {name: \"Frederick Douglass\", canRead: true, canWrite: true}\n// {name: \"Frederick Douglass\", canRead: false, canWrite: false}\n</source>\n\n\nan impure function --it changes DOM\n\n<source lang=\"js\">\nfunction Header(text) {\n  let h1 = document.createElement(\"h1\");\n  h1.innerText = text;\n  document.body.appendChild(h1);\n}\n\nHeader(\"Header() caused side effects\");\n</source>\n\nIn React, UI is expressed with pure functions. e.g.\n\n<source lang=\"js\">\nconst Header = props => <h1>{props.title}</h1>;\n</source>\n\n==== Guideline for writing pure functions ====\n\n# at least one argument\n# return a value or another function\n# should not change or mutate any of its arguments\n\n\n=== Data Transformations ===\n\nvia Array.map and Array.reduce\n\n\nusing Array.join\n\n<source lang=\"js\">\nconst schools = [\"Yorktown\", \"Washington & Lee\", \"Wakefield\"];\n\nconsole.log(schools.join(\", \"));\n\n// \"Yorktown, Washington & Lee, Wakefield\"\n</source>\n\ncreate a new array of the schools that begin with the letter \"W\"\n\n<source lang=\"js\">\nconst wSchools = schools.filter(school => school[0] === \"W\");\n\nconsole.log(wSchools);\n// [\"Washington & Lee\", \"Wakefield\"]\n</source>\n\nwhen removing an item from an array, use Array.filter over .pop() or .splice() because .filter() is immutable\n\n<source lang=\"js\">\nconst cutSchool = (cut, list) => list.filter(school => school !== cut);\n\nconsole.log(cutSchool(\"Washington & Lee\", schools).join(\", \"));\n\n// \"Yorktown, Wakefield\"\n\nconsole.log(schools.join(\"\\n\"));\n\n// Yorktown\n// Washington & Lee\n// Wakefield\n</source>\n\nArray.map takes a function as its argument which will be invoked once for every item in the array, and whatever it returns will be added to the new array\n\n<source lang=\"js\">\nconst highSchools = schools.map(school => `${school} High School`);\n\nconsole.log(highSchools.join(\"\\n\"));\n\n// Yorktown High School\n// Washington & Lee High School\n// Wakefield High School\n\nconsole.log(schools.join(\"\\n\"));\n\n// Yorktown\n// Washington & Lee\n// Wakefield\n</source>\n\ne.g. return an object for every school\n\n<source lang=\"js\">\nconst highSchools = schools.map(school => ({ name: school }));\n\nconsole.log(highSchools);\n\n// [\n// { name: \"Yorktown\" },\n// { name: \"Washington & Lee\" },\n// { name: \"Wakefield\" }\n// ]\n</source>\n\npure f(x) that changes one object in an array of objects\n\n<source lang=\"js\">\nlet schools = [\n  { name: \"Yorktown\" },\n  { name: \"Stratford\" },\n  { name: \"Washington & Lee\" },\n  { name: \"Wakefield\" }\n];\n\nconst editName = (oldName, name, arr) =>\n  arr.map(item => {\n    if (item.name === oldName) {\n      return {\n        ...item,\n        name\n      };\n    } else {\n      return item;\n    }\n  });\n\nlet updatedSchools = editName(\"Stratford\", \"HB Woodlawn\", schools);\n\nconsole.log(updatedSchools[1]); // { name: \"HB Woodlawn\" }\nconsole.log(schools[1]); // { name: \"Stratford\" }\n\n// equivalent to\n\nconst editName = (oldName, name, arr) =>\n  arr.map(item => (item.name === oldName ? { ...item, name } : item));\n</source>\n\ntransform schools object into an array of schools:\n\n<source lang=\"js\">\n\nconst schools = {\n  Yorktown: 10,\n  \"Washington & Lee\": 2,\n  Wakefield: 5\n};\n\nconst schoolArray = Object.keys(schools).map(key => ({\n  name: key,\n  wins: schools[key]\n}));\n\nconsole.log(schoolArray);\n\n// [\n// {\n// name: \"Yorktown\",\n// wins: 10\n// },\n// {\n// name: \"Washington & Lee\",\n// wins: 2\n// },\n// {\n// name: \"Wakefield\",\n// wins: 5\n// }\n// ]\n</source>\n\n\n<code>reduce</code> and <code>reduceRight</code> are used to trasnform an array into any value, including a number, string, boolean, object, or even a function\n\nmaximum number in an array of numbers\n\n<source lang=\"js\">\nconst ages = [21, 18, 42, 40, 64, 63, 34];\n\nconst maxAge = ages.reduce((max, age) => {\n  console.log(`${age} > ${max} = ${age > max}`);\n  if (age > max) {\n    return age;\n  } else {\n    return max;\n  }\n}, 0);\n\nconsole.log(\"maxAge\", maxAge);\n\n// 21 > 0 = true\n// 18 > 21 = false\n// 42 > 21 = true\n// 40 > 42 = false\n// 64 > 42 = true\n// 63 > 64 = false\n// 34 > 64 = false\n// maxAge 64\n\n// equivalent to\n\nconst max = ages.reduce((max, value) => (value > max ? value : max), 0);\n</source>\n\nreduce takes two arguments: a callback function & an original value\n\nreduceRight simply starts reducing from the end of the array rather than the beginning\n\n\ntransform an array into an object\n\n<source lang=\"js\">\nconst colors = [\n  {\n    id: \"xekare\",\n    title: \"rad red\",\n    rating: 3\n  },\n  {\n    id: \"jbwsof\",\n    title: \"big blue\",\n    rating: 2\n  },\n  {\n    id: \"prigbj\",\n    title: \"grizzly grey\",\n    rating: 5\n  },\n  {\n    id: \"ryhbhsl\",\n    title: \"banana\",\n    rating: 1\n  }\n];\n\nconst hashColors = colors.reduce((hash, { id, title, rating }) => {\n  hash[id] = { title, rating };\n  return hash;\n}, {});\n\nconsole.log(hashColors);\n\n// {\n// \"xekare\": {\n// title:\"rad red\",\n// rating:3\n// },\n// \"jbwsof\": {\n// title:\"big blue\",\n// rating:2\n// },\n// \"prigbj\": {\n// title:\"grizzly grey\",\n// rating:5\n// },\n// \"ryhbhsl\": {\n// title:\"banana\",\n// rating:1\n// }\n// }\n</source>\n\nreducing an array with multiple instances of the same value to an array of unique values \n\n<source lang=\"js\">\nconst colors = [\"red\", \"red\", \"green\", \"blue\", \"green\"];\n\nconst uniqueColors = colors.reduce(\n  (unique, color) =>\n    unique.indexOf(color) !== -1 ? unique : [...unique, color],\n  []\n);\n\nconsole.log(uniqueColors);\n\n// [\"red\", \"green\", \"blue\"]\n</source>\n\n\n=== Higher-Order Functions ===\n\nfunctions that can manipulate other functions; can take functions in as arguments, or return functions, or both\n\ne.g.\n<source lang=\"js\">\nconst invokeIf = (condition, fnTrue, fnFalse) =>\n  condition ? fnTrue() : fnFalse();\n\nconst showWelcome = () => console.log(\"Welcome!!!\");\n\nconst showUnauthorized = () => console.log(\"Unauthorized!!!\");\n\ninvokeIf(true, showWelcome, showUnauthorized); // \"Welcome!!!\"\ninvokeIf(false, showWelcome, showUnauthorized); // \"Unauthorized!!!\"\n</source>\n\ne.g. currying\n\n<source lang=\"js\">\nconst userLogs = userName => message =>\n  console.log(`${userName} -> ${message}`);\n\nconst log = userLogs(\"grandpa23\");\n\nlog(\"attempted to load 20 fake members\");\ngetFakeMembers(20).then(\n  members => log(`successfully loaded ${members.length} members`),\n  error => log(\"encountered an error loading members\")\n);\n\n// grandpa23 -> attempted to load 20 fake members\n// grandpa23 -> successfully loaded 20 members\n\n// grandpa23 -> attempted to load 20 fake members\n// grandpa23 -> encountered an error loading members\n</source>\n\n\n=== Recursion ===\n\n<source lang=\"js\">\nconst countdown = (value, fn) => {\n  fn(value);\n  return value > 0 ? countdown(value - 1, fn) : value;\n};\n\ncountdown(10, value => console.log(value));\n\n// 10\n// 9\n// 8\n// 7\n// 6\n// 5\n// 4\n// 3\n// 2\n// 1\n// 0\n</source>\n\nrecursion is well-suited for searching through data structures\n\n<source lang=\"js\">\nconst dan = {\n  type: \"person\",\n  data: {\n    gender: \"male\",\n    info: {\n      id: 22,\n      fullname: {\n        first: \"Dan\",\n        last: \"Deacon\"\n      }\n    }\n  }\n};\n\nconst deepPick = (fields, object = {}) => {\n  const [first, ...remaining] = fields.split(\".\");\n  return remaining.length\n    ? deepPick(remaining.join(\".\"), object[first])\n    : object[first];\n};\n\ndeepPick(\"type\", dan); // \"person\"\ndeepPick(\"data.info.fullname.first\", dan); // \"Dan\"\n\ndeepPick(\"data.info.fullname.first\", dan); // \"Deacon\"\n\n// First Iteration\n// first = \"data\"\n// remaining.join(\".\") = \"info.fullname.first\"\n// object[first] = { gender: \"male\", {info} }\n\n// Second Iteration\n// first = \"info\"\n// remaining.join(\".\") = \"fullname.first\"\n// object[first] = {id: 22, {fullname}}\n\n// Third Iteration\n// first = \"fullname\"\n// remaining.join(\".\" = \"first\"\n// object[first] = {first: \"Dan\", last: \"Deacon\" }\n\n// Finally...\n// first = \"first\"\n// remaining.length = 0\n// object[first] = \"Deacon\"\n\n</source>\n\n\n=== Composition ===\n\nchaining\n\n<source lang=\"js\">\nconst template = \"hh:mm:ss tt\";\nconst clockTime = template\n  .replace(\"hh\", \"03\")\n  .replace(\"mm\", \"33\")\n  .replace(\"ss\", \"33\")\n  .replace(\"tt\", \"PM\");\n\nconsole.log(clockTime);\n\n// \"03:33:33 PM\"\n</source>\n\n<code>both</code> function pipes a value through two separate functions. \n\n<source lang=\"js\">\nconst both = date => appendAMPM(civilianHours(date));\n\n// but hard to read, so better approach is to use higher order function\n\nconst compose = (...fns) => arg =>\n  fns.reduce((composed, f) => f(composed), arg);\n\nconst both = compose(\n  civilianHours,\n  appendAMPM\n);\n\nboth(new Date());\n</source>\n\n== Putting it all together ==\n\n\nticking time\n\n<source lang=\"js\">\n// Log Clock Time every Second\nsetInterval(logClockTime, 1000);\n\nfunction logClockTime() {\n  // Get Time string as civilian time\n  let time = getClockTime();\n\n  // Clear the Console and log the time\n  console.clear();\n  console.log(time);\n}\n\nfunction getClockTime() {\n  // Get the Current Time\n  let date = new Date();\n  let time = \"\";\n\n  // Serialize clock time\n  let time = {\n    hours: date.getHours(),\n    minutes: date.getMinutes(),\n    seconds: date.getSeconds(),\n    ampm: \"AM\"\n  };\n\n  // Convert to civilian time\n  if (time.hours == 12) {\n    time.ampm = \"PM\";\n  } else if (time.hours > 12) {\n    time.ampm = \"PM\";\n    time.hours -= 12;\n  }\n\n  // Prepend a 0 on the hours to make double digits\n  if (time.hours < 10) {\n    time.hours = \"0\" + time.hours;\n  }\n\n  // prepend a 0 on the minutes to make double digits\n  if (time.minutes < 10) {\n    time.minutes = \"0\" + time.minutes;\n  }\n\n  // prepend a 0 on the seconds to make double digits\n  if (time.seconds < 10) {\n    time.seconds = \"0\" + time.seconds;\n  }\n\n  // Format the clock time as a string \"hh:mm:ss tt\"\n  return time.hours + \":\" + time.minutes + \":\" + time.seconds + \" \" + time.ampm;\n}\n</source>\n\nREFACTORING using what we learned\n\n\nin functional programs, use functions over values wherever possible; invoke the function to obtain the value when needed\n\n<source lang=\"js\">\nconst oneSecond = () => 1000;\nconst getCurrentTime = () => new Date();\nconst clear = () => console.clear();\nconst log = message => console.log(message);\n</source>\n\nthree functions will be used to mutate the clock\n# serializeClockTime - take a date object and returns a object for clock time that contains hours minutes, and seconds.\n# civilianHours - takes the clock time object and returns an object where hours are converted to civilian time (1300 becomes 1:00)\n# appendAMPM - take the clock time object and appends time of day, AM or PM, to that object.\n\n<source lang=\"js\">\nconst serializeClockTime = date => ({\n  hours: date.getHours(),\n  minutes: date.getMinutes(),\n  seconds: date.getSeconds()\n});\n\nconst civilianHours = clockTime => ({\n  ...clockTime,\n  hours: clockTime.hours > 12 ? clockTime.hours - 12 : clockTime.hours\n});\n\nconst appendAMPM = clockTime => ({\n  ...clockTime,\n  ampm: clockTime.hours >= 12 ? \"PM\" : \"AM\"\n});\n</source>\n\nhigher order functions needed\n# display - takes a target function and returns a function that will send a time to the target. In this eample the target will be console.log\n# formatClock - takes a template string and uses it to return clock time formatted based upon the criteria from the string. \n# prependZero - \n\n<source lang=\"js\">\nconst display = target => time => target(time);\n\nconst formatClock = format => time =>\n  format\n    .replace(\"hh\", time.hours)\n    .replace(\"mm\", time.minutes)\n    .replace(\"ss\", time.seconds)\n    .replace(\"tt\", time.ampm);\n\nconst prependZero = key => clockTime => ({\n  ...clockTime,\n  [key]: clockTime[key] < 10 ? \"0\" + clockTime[key] : clockTime[key]\n});\n</source>\n\n\ncompose\n\n<source lang=\"js\">\nconst convertToCivilianTime = clockTime =>\n  compose(\n    appendAMPM,\n    civilianHours\n  )(clockTime);\n\nconst doubleDigits = civilianTime =>\n  compose(\n    prependZero(\"hours\"),\n    prependZero(\"minutes\"),\n    prependZero(\"seconds\")\n  )(civilianTime);\n\nconst startTicking = () =>\n  setInterval(\n    compose(\n      clear,\n      getCurrentTime,\n      serializeClockTime,\n      convertToCivilianTime,\n      doubleDigits,\n      formatClock(\"hh:mm:ss tt\"),\n      display(log)\n    ),\n    oneSecond()\n  );\n\nstartTicking();\n</source>\n\n\n= How React Works =\n\n\n== React elements ==\n\n<source lang=\"js\">\nReact.createElement(\"h1\", { id: \"recipe-0\" }, \"Baked Salmon\");\n\n// <h1 id=\"recipe-0\">Baked Salmon</h1>\n\n// log:\n{\n  $$typeof: Symbol(React.element),\n  \"type\": \"h1\",\n  \"key\": null,\n  \"ref\": null,\n  \"props\": {id: \"recipe-0\", children: \"Baked Salmon\"},\n  \"_owner\": null,\n  \"_store\": {}\n}\n</source>\n\n\n== ReactDOM ==\n\ncontains tools necessary to render React element in the browser via '''render''' method\n\n<source lang=\"js\">\nconst dish = React.createElement(\"h1\", null, \"Baked Salmon\");\n\nReactDOM.render(dish, document.getElementById(\"root\"));\n</source>\n\nrendering array of elements\n\n<source lang=\"js\">\nconst dish = React.createElement(\"h1\", null, \"Baked Salmon\");\nconst dessert = React.createElement(\"h2\", null, \"Coconut Cream Pie\");\n\nReactDOM.render([dish, dessert], document.getElementById(\"root\"));\n</source>\n\n\n== Children ==\n\n<source lang=\"js\">\nReact.createElement(\n  \"ul\",\n  null,\n  React.createElement(\"li\", null, \"2 lb salmon\"),\n  React.createElement(\"li\", null, \"5 sprigs fresh rosemary\"),\n  React.createElement(\"li\", null, \"2 tablespoons olive oil\"),\n  React.createElement(\"li\", null, \"2 small lemons\"),\n  React.createElement(\"li\", null, \"1 teaspoon kosher salt\"),\n  React.createElement(\"li\", null, \"4 cloves of chopped garlic\")\n);\n\n// equivalent to\n\nconst items = [\n  \"2 lb salmon\",\n  \"5 sprigs fresh rosemary\",\n  \"2 tablespoons olive oil\",\n  \"2 small lemons\",\n  \"1 teaspoon kosher salt\",\n  \"4 cloves of chopped garlic\"\n];\n\nReact.createElement(\n  \"ul\",\n  { className: \"ingredients\" },\n  items.map((ingredient, i) => React.createElement(\"li\", { key: i }, ingredient))\n);\n</source>\n\n\n== React Components ==\n\n\n<source lang=\"js\">\nfunction IngredientsList({ items }) { // destructure items from props\n  return React.createElement(\n    \"ul\",\n    { className: \"ingredients\" },\n    items.map((ingredient, i) => React.createElement(\"li\", { key: i }, ingredient)\n  );\n}\n\nconst items = [\n  \"2 lb salmon\",\n  \"5 sprigs fresh rosemary\",\n  \"2 tablespoons olive oil\",\n  \"2 small lemons\",\n  \"1 teaspoon kosher salt\",\n  \"4 cloves of chopped garlic\"\n];\n\nReactDOM.render(\n  React.createElement(IngredientsList, { items }, null),\n  document.getElementById(\"root\")\n);\n</source>\n\nuse functions to create components because class syntax is being deprecated.\n\n= React with JSX =\n\n== React elements as JSX ==\n\n=== Nested components ===\n\n<source lang=\"html\">\n<IngredientsList>\n  <Ingredient />\n  <Ingredient />\n  <Ingredient />\n</IngredientsList>\n</source>\n\n\n=== ClassName ===\n\nSince <code>class</code> is a reserved word in JavaScript, className is used to define the class attribute.\n\n\n=== JavaScript Expressions ===\n\n<source lang=\"js\">\n<h1>{title}</h1>\n\n<input type=\"checkbox\" defaultChecked=\"{false}\" />\n</source>\n\n\n=== Evaluation ===\n\n<source lang=\"js\">\n<h1>{\"Hello\" + title}</h1>\n\n<h1>{title.toLowerCase().replace}</h1>\n\nfunction appendTitle({ title }) {\n  console.log(`${title} is great!`);\n}\n</source>\n\n\n=== Mapping Arrays with JSX ===\n\n<source lang=\"js\">\n<ul>\n  {props.ingredients.map((ingredient, i) => (\n    <li key=\"{i}\">{ingredient}</li>\n  ))}\n</ul>\n</source>\n\n\n== Babel ==\n\ntemplate file to use\n\n<source lang=\"html\">\n<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>React Examples</title>\n  </head>\n  <body>\n    <div id=\"root\"></div>\n\n    <!-- React Library & React DOM -->\n    <script src=\"https://unpkg.com/react@16.8.6/umd/react.development.js\"></script>\n    <script src=\"https://unpkg.com/react-dom@16.8.6/umd/react-dom.development.js\"></script>\n    <script src=\"https://unpkg.com/@babel/standalone/babel.min.js\"></script>\n\n    <script type=\"text/babel\">\n      // JSX code here. Or link to separate JavaScript file that contains JSX.\n    </script>\n  </body>\n</html>\n</source>\n\n\n== Recipes as JSX ==\n\n<source lang=\"js\">\nconst data = [\n  {\n    name: \"Baked Salmon\",\n    ingredients: [\n      { name: \"Salmon\", amount: 1, measurement: \"l lb\" },\n      { name: \"Pine Nuts\", amount: 1, measurement: \"cup\" },\n      { name: \"Butter Lettuce\", amount: 2, measurement: \"cups\" },\n      { name: \"Yellow Squash\", amount: 1, measurement: \"med\" },\n      { name: \"Olive Oil\", amount: 0.5, measurement: \"cup\" },\n      { name: \"Garlic\", amount: 3, measurement: \"cloves\" }\n    ],\n    steps: [\n      \"Preheat the oven to 350 degrees.\",\n      \"Spread the olive oil around a glass baking dish.\",\n      \"Add the yellow squash and place in the oven for 30 mins.\",\n      \"Add the salmon, garlic, and pine nuts to the dish.\",\n      \"Bake for 15 minutes.\",\n      \"Remove from oven. Add the lettuce and serve.\"\n    ]\n  },\n  {\n    name: \"Fish Tacos\",\n    ingredients: [\n      { name: \"Whitefish\", amount: 1, measurement: \"l lb\" },\n      { name: \"Cheese\", amount: 1, measurement: \"cup\" },\n      { name: \"Iceberg Lettuce\", amount: 2, measurement: \"cups\" },\n      { name: \"Tomatoes\", amount: 2, measurement: \"large\" },\n      { name: \"Tortillas\", amount: 3, measurement: \"med\" }\n    ],\n    steps: [\n      \"Cook the fish on the grill until cooked through.\",\n      \"Place the fish on the 3 tortillas.\",\n      \"Top them with lettuce, tomatoes, and cheese.\"\n    ]\n  }\n];\n\n// A function component for an individual Recipe\nfunction Recipe (props) {\n  ...\n}\n\n// A function component for the Menu of Recipes\nfunction Menu (props) {\n  return (\n    <article>\n      <header>\n        <h1>{props.title}</h1>\n      </header>\n<div className=\"recipes\">\n  {props.recipes.map((recipe, i) => (\n    <Recipe\n      key={i}\n      name={recipe.name}\n      ingredients={recipe.ingredients}\n      steps={recipe.steps}\n    />\n  ))}\n// equivalent to\n{\n  props.recipes.map((recipe, i) => <Recipe key={i} {...recipe} />);\n}\n</div>\n    </article>\n  );\n}\n\n// A call to ReactDOM.render to render our Menu into the current DOM\nReactDOM.render(\n  <Menu recipes={data} title=\"Delicious Recipes\" />,\n  document.getElementById(\"root\")\n);\n</source>\n\n\nwe can access title & recipes vars directly, so vars don't have to be prefixed with props:\n\n<source lang=\"js\">\nfunction Menu({ title, recipes }) {\n  return (\n    <article>\n      <header>\n        <h1>{title}</h1>\n      </header>\n      <div className=\"recipes\">\n        {recipes.map((recipe, i) => (\n          <Recipe key={i} {...recipe} />\n        ))}\n      </div>\n    </article>\n  );\n}\n</source>\n\n\ncode for the component for each individual recipe:\n\n<source lang=\"js\">\nfunction Recipe({ name, ingredients, steps }) {\n  return (\n    <section id={name.toLowerCase().replace(/ /g, \"-\")}>\n      <h1>{name}</h1>\n      <ul className=\"ingredients\">\n        {ingredients.map((ingredient, i) => (\n          <li key={i}>{ingredient.name}</li>\n        ))}\n      </ul>\n      <section className=\"instructions\">\n        <h2>Cooking Instructions</h2>\n        {steps.map((step, i) => (\n          <p key={i}>{step}</p>\n        ))}\n      </section>\n    </section>\n  );\n}\n</source>\n\n\n== React fragments ==\n\n<source lang=\"js\">\nfunction Cat({ name }) {\n  return (\n    <React.Fragment>\n      <h1>The cat's name is {name}</h1>\n      <p>He's good.</p>\n    </React.Fragment>\n  );\n}\n\n// equivalent to\n\nfunction Cat({ name }) {\n  return (\n    <>\n      <h1>The cat's name is {name}</h1>\n      <p>He's good.</p>\n    </>\n  );\n}\n</source>\n\n\n== Intro to webpack ==\n\n* Code splitting\n* Minification\n* Feature flagging\n* Hot module replacement (HMR)\n* Modularity\n* Composition\n* Speed\n* Consistency\n\n\nInstalling webpack\n\n<source lang=\"console\">\n$ npm install --save-dev webpack@next webpack-cli\n</source>\n\n\nInstalling Babel dependencies\n\n<source lang=\"console\">\n$ npm install babel-loader @babel/core --save-dev\n</source>\n\n\nSpecify Babel presets\n\n<source lang=\"console\">\n$ npm install @babel/preset-env @babel/preset-react --save-dev\n</source>\n\n\n= React State Management =\n\n\n= Reference =\n\n* [https://react-icons.netlify.com React Icons]\n* Personal blogs\n** [https://www.leighhalliday.com Leigh Halliday]\n** [https://www.robinwieruch.de Robin Wieruch]"
                    }
                ]
            },
            "1157": {
                "pageid": 1157,
                "ns": 0,
                "title": "Ronson butane lighter",
                "revisions": [
                    {
                        "contentformat": "text/x-wiki",
                        "contentmodel": "wikitext",
                        "*": "How to fill a Ronson butane lighter\n\n# Use a small screwdriver to turn the screw on the bottom of the butane lighter to \"-\" position.\n# Turn the lighter upside down.\n# Insert the butane tip into the inlet valve on the lighter. Hold the lighter and the butane upside down when filling.\n# Press the butane valve down on the inlet valve and hold for 5 seconds. Repeat this once more and lighter will be filled.\n# Light the lighter and adjust the flame, which will be higher than what you need after filling."
                    }
                ]
            }
        }
    }
}