{"id":17652398,"url":"https://github.com/bashleigh/teaching","last_synced_at":"2025-06-15T02:08:49.552Z","repository":{"id":103668511,"uuid":"191214084","full_name":"bashleigh/teaching","owner":"bashleigh","description":"Teaching session for Southend high school for boys","archived":false,"fork":false,"pushed_at":"2019-06-15T19:43:07.000Z","size":496,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-30T09:12:59.693Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bashleigh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-06-10T17:27:02.000Z","updated_at":"2019-07-16T09:44:03.000Z","dependencies_parsed_at":null,"dependency_job_id":"83cc1625-cc63-43bd-82ea-205cc3856833","html_url":"https://github.com/bashleigh/teaching","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bashleigh/teaching","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bashleigh%2Fteaching","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bashleigh%2Fteaching/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bashleigh%2Fteaching/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bashleigh%2Fteaching/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bashleigh","download_url":"https://codeload.github.com/bashleigh/teaching/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bashleigh%2Fteaching/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259910730,"owners_count":22930711,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-23T11:46:53.360Z","updated_at":"2025-06-15T02:08:49.535Z","avatar_url":"https://github.com/bashleigh.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Teaching\n\nTeaching session for Southend high school for boys\n\n# Introduction\n\nECMAScript (also known as ES) is a standardisation of JavaScript. Both are technically the 'same thing' however ECMAScript has more updated version like ES5, ES6, ES7, ES8 etc. ES6 is the most commonly spoken about on the internet at the moment however ES5 is the most common. ES5 being the original JavaScript or \"vanilla\".\n\nWhen ES6 was released (the current engine used by google chrome) there were several additions such as classes for OOP (Object Orientated Programming) and 'async await' asynchronous methodology. \n\n# Section 1\n\n## Cheatsheet\n\n### Syntax\n\n#### Semicolons\n\nSemicolons are optional in ES6+. I'm old so I put them in.\n\n#### Consts and lets \n\nConstants are 'constantly' only ever one thing. Like so:\n```es6\nconst constant = 'I cannot be changed.';\n```\nOnce a constant has been declared, you cannot redeclare a constant.\n```es6\nconst constant = 'I cannot be changed.';\nconsant = 'I changed'; // will throw an exception\n```\n\nLet's are able to be redefined within the scope like so\n```es6\nlet changeMe = 123;\nchangeMe = 333;\nchangeMe += 1;\nconsole.log('changeMe', changeMe);\n```\nThe above will output \n```\nChangeMe 334\n```\n\n#### Exceptions\nAn exception is like an error. If someone says 'throw an exception' it just means your saying something like \"Hey, it didn't work.\"\n\n```es6\nthrow new Error('I is error');\n```\n#### Functions\nFunction in ES are similar to any other language. You can define a global function like this\n\n```es6\nfunction IAmAFunction(parameter = 'test') {\n  console.log(`IAmAFunction said this: ${parameter}`);\n  return parameter;\n}\n\nconst result = IAmAFunction('hello');\nconst result2 = IAmAFunction();\n```\n`result` will equal 'hello'. \n`result` will equal 'test'.\n\n#### Objects \n\n```es6\nconst object = {};\n```\n\n#### Arrays\n```es6\nconst array = [];\n```\n\n##### Cool array function\n\n**filter**\n\nArray.filter will return a new array without the items that didn't match the condition. \n\n```es6\nconst arrayOfNumbers = [1,3,4,7,2,8,10];\n\nconst under5 = arrayOfNumbers.filter(function (number) {\n  return number \u003c 5;\n});\n```\n\n**map**\n```es6 \nconst arrayOfPeople = [\n  {\n    name: 'Jeff',\n    age: 20,\n  },\n  {\n    name: 'Bob',\n    age: 22,\n  },\n];\n\narrayOfStuff.map(function (person) {\n  person.age++;\n});\n```\n\n**forEach**\n\nThe Array.forEach method is rather handy, it will loop over every item in the array in order. It's much like the old ES5 way of doing it like this `for (int i = array.length; i \u003e 0; i--) {}`\n\n```es6 \nconst arrayOfPeople = [\n  {\n    name: 'Jeff',\n    age: 20,\n  },\n  {\n    name: 'Bob',\n    age: 22,\n  },\n];\n\narrayOfStuff.forEach(function (person) {\n  console.log(`Hello! ${person.name}!`);\n});\n```\n\n**switches**\n\n```es6\nconst thing = 'this';\n\nswitch (thing) {\n  case 'test':\n    console.log('thing === test');\n    break;\n  case 'this':\n    console.log('thing === this');\n    break;\n}\n```\n\n```es6\nconst thing = 123;\n\nswitch (thing) {\n  case 'test':\n    console.log('thing === test');\n    break;\n  case 'this':\n    console.log('thing === this');\n    break;\n  default:\n    console.log('thing !== test or this');\n}\n```\n**if statements and conditions**\n```es6\nconst checkMe = 'hello';\n\nif (checkMe === 'hello') {\n  console.log('you said hello');\n} \n```\nexample 1\n```es6\nconst checkMe = 'goodbye';\n\nif (checkMe === 'hello') {\n  console.log('you said hello');\n} else if (checkMe === 'goodbye') {\n  console.log('you said goodbye');\n}\n```\nexample 2\n```es6 \nconst checkMe = 'Alexa, make a fart noise';\n\nif (checkMe === 'hello') {\n  console.log('you said hello');\n} else if (checkMe === 'goodbye') {\n  console.log('you said goodbye');\n} else {\n  console.log('you didn\\'t say goodbye or hello');\n}\n```\nexample 3 \n```es6\nconst checkMe = 'Alexa, make a fart noise';\n\nconst words = checkMe.split(' ');\n\nif (words[0] === 'Alexa,' \u0026\u0026 words[3] === 'fart' \u0026\u0026 words[4] === 'noise') {\n  console.log('FARRRTTTT');\n}\n```\nexample 4 \n```es6\nconst checkMe = 'Alexa, fart noise';\n\nconst words = checkMe.split(' ');\n\nif (words[0] === 'Alexa,') {\n  if (\n  (words[3] === 'fart' \u0026\u0026 words[4] === 'noise')\n  || (words[1] === 'fart' \u0026\u0026 words[2] === 'noise')\n ) {\n    console.log('FARRRTTTT');\n  }\n}\n```\nexample 5 \n\n```es6\nconst boolean = true;\n\nif (boolean) {\n  console.log('boolean is true');\n}\n```\n\n```es6\nconst boolean = false;\n\nif (!boolean) {\n  console.log('boolean is false');\n}\n```\n\n\u003e Notice above the `!` reverses what the boolean is. If boolean = true, !boolean === false and vis-ver-sa. If boolean = false, !boolean === true;\n\n## Section 2 Why use node.js and ECMAScript \n\nSo ECMAScript is JavaScript and JavaScript has always been a front end, client based language designed to be run in client applications such as a browser these days. Node.js is a platform that enables you to use the language JavaScript as a backend process. A process is a script that's running on your machine. This could be anything! Any application running on your computer can utilise several scripts at the same time.  \n\nUsing the command `ps aux` on a linux based machine we can see a list of all the commands/processes running on that machine \n\n![processes](./process.png)\n\nWith node we can create a script and run that script using the node executable on your window computer. \n\n```cmd\nC:\\\\ F:\\nodejs\\node.exe -e \"console.log('hello!');\"\n```\n### Using node.js as a web server compared to other servers \nNode is capable of running of as a web server by listen to a port on your machine. Compared to other web servers and languages nodejs is quite unique as it makes a clone of itself when a request is incoming. Meaning it spends less time 'booting' itself up.\n\nOther web servers and languages usually take time booting themselves up so nodejs reduces the time a person is awaiting a response from the service. \n\nYou can build a simple web server like so:\n\n```es6\n// server.js\nconst http = require('http');\n\nconst server = http.createServer(function (request, response) {\n  console.log('we have a hit!');\n  response.write('Hello!');\n  response.end();\n});\n\nserver.listen(3000, function() {\n  console.log('Listening to port 3000 for requests');\n});\n```\nYou can run this script like so\n\n```cmd\nC:\\\\ F:\\nodejs\\node.exe server.js\n```\n\nOnce the process prints the line \"Listening to port 3000 for requests\" the server is ready and listening! You can now request `http://localhost:3000/`. You should get a response back with `Hello!`\n\n## Section 3 What can I do with it?\n\nA common thing for all websites/services/agencies/client etc is something called REST or CRUD. Everyone seems to have their own interpretation of what those letters mean but basically it means that you can Create, Review, Update, Delete something. \n\nLet's say that we have a website that sells cats. In order to display what cats we have on our website we need to be able to create a cat. We also need to be able to see all the cats and usually show 1 cat at a time. \n\nFor now we'll miss out Create, Edit and Delete and focus on the different Review actions to start simple.\n\nWe do this by using something known as the URI. A URL (not URI) is something like `http://buymycats.com/cats/tom-cat`. The URI is the part after the `.com` or `.co.uk` or whatever our domain is. So on our server we can tell what people are requesting. If the URI is `cats/` we want to get all cats. If the URI is `cats/tom-cat` we want a cat with the name `tom-cat`.\n\nIn this example is a file called `cats.json` this file contains an array of cats in the JSON format.\n\n#### What to do \n\nSo we have this file called `cats.json`, we want to read the file and return the contents of the file to the user making the request. We can read the file using a library supplied by nodejs. \n\n```es6\nconst fs = require('fs');\n```\n`fs` stands for 'file-system'. No idea why they didn't call it that but yea.\n\nWe can use fs to read our file and get our cat objects.\n\n```es6\nconst fs = require('fs');\n\nlet cats = [];\n\nconst fileContent = fs.readFileSync('./cats.json', 'utf8');\n\ncats = JSON.parse(fileContent);\n```\n\nNow we have our cats! Now we've got to render them to the user making the request. But! Only when the URI is `cats` and nothing else. \n\n```es6\nconst http = require('http');\n\nconst fs = require('fs');\n\nlet cats = [];\n\nconst fileContent = fs.readFileSync('./cats.json', 'utf8');\n\ncats = JSON.parse(fileContent);\n\nconst server = http.createServer(function (request, response) {\n  response.writeHead(200, {'Content-Type': 'application/json'});\n  \n  switch (request.url) {//confusing I know, node calls uri url :thumbs-up: well done nodejs\n    case 'cats':\n    case '/cats':\n    case '/cats/':\n    case 'cats/':\n      response.write(JSON.stringify(cats));\n      break;\n\n    default:\n      response.writeHead(404);\n      response.write('Invalid URI');\n  }\n\n  response.end();\n});\n\nserver.listen(3000, function() {\n  console.log('Listening to port 3000 for requests');\n});\n```\n\n### Using slugs\n\nSo you might of noticed in the JSON there's a key called `slug` in the dev world we use this work to determine a unique name of our objects. Or in this instance our cats. Our cats each have a name but! This name isn't always unique! So we have a unique name for them and this is called a slug. It's the same for username's on some social media sites and the like. \n\nSo to get our cat we need to request it using the slug like so `http://localhost:3000/cats/luke-skywalker`. To return the cat Luke Skywalker we need to find him in the array and return him. We can do that like so\n\n```es6\n\nconst slug = 'luke-skywalker';\n\nconst matches = cats.filter(function (cat) {\n  return cat.slug === slug;\n});\n\n```\n\n`cats.filter` will return an array of cats that have the slug which matches `luke-skywalker`. We know that there can be only one so this array will either contain 1 cat object or nothing. From this we can determine that what the user has asked for exists. Because if there are no objects in the array then the user requested something that doesn't exist and we can tell them to go away because we canny do what they asked. \n\n```es6\nif (matches.length !== 1) {\n  res.writeHead(404); // 404 is the http status code for not found.\n}\n```\n\n#### So how do we do this in our server?\n\nUsing something called 'regular expressions' or Regex for short, we're going to check to see if our URI contains \n\n```es6\nconst http = require('http');\n\nconst fs = require('fs');\n\nlet cats = [];\n\nconst fileContent = fs.readFileSync('./cats.json', 'utf8');\n\ncats = JSON.parse(fileContent);\n\nconst server = http.createServer(function (request, response) {\n  response.writeHead(200, {'Content-Type': 'application/json'});\n\n  if (/^\\/cats\\/\\w+/.test(request.url)) {\n    const uriParts = request.url.split('/');\n    const slug = uriParts[2]; // because [0] =\u003e '', [1] =\u003e cats, [2] =\u003e luke-sykwalker\n\n    const matches = cats.filter(function(cat) {\n      return cat.slug === slug;\n    });\n\n    if (matches.length !== 1) {\n      response.writeHead(404);\n      response.write('Cat not found');\n      response.end();\n      return;\n    }\n\n    response.write(JSON.stringify(matches[0]));\n    response.end();\n    return;\n  }\n  \n  switch (request.url) {\n    case 'cats':\n    case '/cats':\n    case '/cats/':\n    case 'cats/':\n      response.write(JSON.stringify(cats));\n      break;\n\n    default:\n      response.writeHead(404);\n      response.write('Invalid URI');\n  }\n\n  response.end();\n});\n\nserver.listen(3000, function() {\n  console.log('Listening to port 3000 for requests');\n});\n```\n\n## Section 4 Cleaning up\n\nWhen developing, another developer cannot read another developers code. Apparently it's like the law or something so yea. So you need to make your code as 'clean' and readable as possible. In the above example we can clean this up by cleaning up the different Review methods into functions and calling them based on a route matcher (route relating to our URI).\n\nSo firstly let's take the easy one to make a function with and that's the show Review method. \n\n```es6\nfunction showAction(request, response) {\n  const uriParts = request.url.split('/');\n  const slug = uriParts[1]; // because [0] =\u003e cats, [1] =\u003e luke-sykwalker\n\n  const matches = cats.filter(function(cat) {\n    return cat.slug === slug;\n  });\n\n  if (matches.length !== 1) {\n    response.writeHead(404);\n    response.write('Cat not found');\n    return response;\n  }\n\n  response.write(JSON.stringify(matches[0]));\n  return response;\n}\n```\n\nAnother function we can make to clean up is the index Review action thing. I'm also ganna replace the switch because it looks crap and we don't need it anymore. \n\n```es6\nfunction indexAction(request, response) {\n  response.write(JSON.stringify(cats));\n  return response;\n}\n```\nLooks a lot neater right? Especially without the switch and lots of if statements all over the place. \n\nNext we'll make a router based on configuration. The configuration is something we can make up. It's going to be based on matching the regex to a function. Basically it's going to say \"does the uri match the regex, if so call the function\".\n\nFirst we need out configuration. I have this idea in my head like this because I want to loop over my configurations to check it matches\n\n```es6\nconst routes = [\n  {\n    \"regex\": /^\\/cats$/,\n    \"function\": indexAction,\n  },\n  {\n    regex: /^\\/cats\\/$/, // this is so we can match '/cats' and '/cats/'\n    function: indexAction,\n  },\n  {\n    \"regex\": /^\\/cats\\/\\w+/,\n    \"function\": showAction,\n  },\n];\n```\n\nThe above has created an array of objects, the objects contain 2 keys, one called regex for checking against and one called function which contains the actual function that we will want to call.\n\nSo now! We want to make our methods callable, so we'll need to change our server to work like so.\n\n```es6\nconst http = require('http');\n\n//functions here with cats etc\n\nconst server = http.createServer(function(request, response) { \n  let routeFound = false;\n  routes.forEach(function(route) {\n    if (request.url.test(route.regex)) {\n      response = route.function(request, response);\n      \n      response.writeHead(200, {'Content-Type': 'application/json'});\n\n      routeFound = true;\n    }\n  });\n\n  if (!routeFound) {\n    response.writeHead(404);\n    response.write('Not found');\n  }\n\n  response.end();\n});\n```\n\nAll in all, our application should look something like this \n\n```es6\nconst http = require('http');\nconst fs = require('fs');\n\nlet cats = [];\n\nconst fileContent = fs.readFileSync('./cats.json', 'utf8');\n\nconst routes = [\n  {\n    \"regex\": /^\\/cats$/,\n    \"function\": indexAction,\n  },\n  {\n    regex: /^\\/cats\\/$/,\n    function: indexAction,\n  },\n  {\n    \"regex\": /^\\/cats\\/\\w+/,\n    \"function\": showAction,\n  },\n];\n\ncats = JSON.parse(fileContent);\n\nfunction showAction(request, response) {\n  const uriParts = request.url.split('/');\n  const slug = uriParts[1]; // because [0] =\u003e cats, [1] =\u003e luke-sykwalker\n\n  const matches = cats.filter(function(cat) {\n    return cat.slug === slug;\n  });\n\n  if (matches.length !== 1) {\n    response.writeHead(404);\n    response.write('Cat not found');\n    return response;\n  }\n\n  response.write(JSON.stringify(matches[0]));\n  return response;\n}\n\nfunction indexAction(request, response) {\n  response.write(JSON.stringify(cats));\n  return response;\n}\n\nconst server = http.createServer(function(request, response) { \n  if (request.url === '/favicon.ico') { // Because google is annoying and breaks my amazing router. Booooo\n    return;\n  }\n  let routeFound = false;\n  routes.forEach(function(route) {\n    if (request.url.test(route.regex)) {\n      response = route.function(request, response);\n      \n      response.writeHead(200, {'Content-Type': 'application/json'});\n\n      routeFound = true;\n    }\n  });\n\n  if (!routeFound) {\n    response.writeHead(404);\n    response.write('Not found');\n  }\n\n  response.end();\n});\n\nserver.listen(3000, function() {\n  console.log('Listening to port 3000');\n});\n```\n\n## Using exceptions \n\nExceptions are pretty handy! In this example I'm going to use them to show a not found page whenever I throw the exception.  \nit's handy to do this because it saves writing awful return statements etc.\n\n```es6\nconst http = require('http');\nconst fs = require('fs');\n\nlet cats = [];\n\nconst fileContent = fs.readFileSync('./cats.json', 'utf8');\n\nconst routes = [\n  {\n    regex: /^\\/cats$/,\n    function: indexAction,\n  },\n  {\n    regex: /^\\/cats\\/$/,\n    function: indexAction,\n  },\n  {\n    regex: /^\\/cats\\/\\w+/,\n    function: showAction,\n  },\n];\n\ncats = JSON.parse(fileContent);\n\nfunction HttpException(message, code) {\n  this.message = message;\n  this.code = code;\n\n  return this;\n}\n\nfunction NotFoundException() {\n  return HttpException('Not Found', 404);\n}\n\nfunction showAction(request, response) {\n  const uriParts = request.url.split('/');\n  const slug = uriParts[2]; // because [0] =\u003e '', [1] =\u003e cats, [2] =\u003e luke-sykwalker\n\n  const matches = cats.filter(function(cat) {\n    return cat.slug === slug;\n  });\n\n  if (matches.length !== 1) {\n    throw new NotFoundException();\n  }\n\n  response.write(JSON.stringify(matches[0]));\n  return response;\n}\n\nfunction indexAction(request, response) {\n  response.write(JSON.stringify(cats));\n  return response;\n}\n\nconst server = http.createServer(function(request, response) { \n  if (request.url === '/favicon.ico') {\n    return;\n  }\n  try {\n\n    const matchedRoute = routes.filter(function (route) {\n      return route.regex.test(request.url);\n    });\n\n    if (matchedRoute.length === 0) {\n      throw new NotFoundException();\n    }\n    response.writeHead(200, {'Content-Type': 'application/json'});\n    response = matchedRoute[0].function(request, response);\n\n  } catch(error) {\n    response.writeHead(error.code);\n    response.write(error.message);\n  }\n\n  response.end();\n});\n\nserver.listen(3000, function() {\n  console.log('Listening to port 3000');\n});\n\n```\n\nNow I can throw this wherever! Including within the showAction where a cat doesn't exist.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbashleigh%2Fteaching","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbashleigh%2Fteaching","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbashleigh%2Fteaching/lists"}