From dba43ff14634c68150c7fc967aa18e4fb7d4a41b Mon Sep 17 00:00:00 2001 From: "Mark Tyers (aa7401)" Date: Thu, 12 Sep 2019 11:14:48 +0100 Subject: [PATCH 1/6] updated link to Koa --- 02 HTTP.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/02 HTTP.md b/02 HTTP.md index e6df50ae..ada25325 100644 --- a/02 HTTP.md +++ b/02 HTTP.md @@ -1,9 +1,11 @@ # The HTTP Protocol -In the lecture you learned about the HTTP protocol which is used to transfer information between web server and the web browser. Without this the World-Wide Web (WWW) would not exist. This lab will allow you to apply this knowledge and learn the details. In this lab you will be using the [NodeJS](http://nodejs.org) [Express package](https://www.npmjs.com/package/express) to write scripts that make use of this protocol. +In the lecture you learned about the HTTP protocol which is used to transfer information between web server and the web browser. -The HTTP protocol is used by web servers to send content to devices such as web browsers. It uses a [request-response](https://en.wikipedia.org/wiki/Request–response) mechanism which involves a _client_ device sending a request to the server. This request includes: +The HTTP protocol is used by web servers to send content to devices such as web browsers. Without this the World-Wide Web (WWW) would not exist. In this lab you will be using the [NodeJS](http://nodejs.org) language running the [Koa web server](https://www.npmjs.com/package/koa) to write scripts that make use of this protocol. + +HTTP uses a [request-response](https://en.wikipedia.org/wiki/Request–response) mechanism which involves a _client_ device sending a request to the server. This request includes: 1. The _resource_ it is requesting (defined as a [URL](https://en.wikipedia.org/wiki/URL)). 2. Additional information such as filters (provided as one or more [query strings](https://en.wikipedia.org/wiki/Query_string)). From 0b5cf5789f05eadf4a8293aed646806d29adb6be Mon Sep 17 00:00:00 2001 From: "Mark Tyers (aa7401)" Date: Thu, 12 Sep 2019 11:16:41 +0100 Subject: [PATCH 2/6] updated resource links --- 03 HTML5.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/03 HTML5.md b/03 HTML5.md index b822f14d..88c06459 100644 --- a/03 HTML5.md +++ b/03 HTML5.md @@ -21,7 +21,7 @@ You should get into the habit of doing this each time you sit down to work on yo ## 1 Syntax -Lets take a look at some basic HTML syntax. Start by locating the `exercises/02_html/01_syntax/` directory. Navigate to this using the SSH Terminal, install the all the necessary `koa` packages and start the web server. If you navigate to the base route `/` you will see a screen full of text. +Lets take a look at some basic HTML syntax. Start by locating the `exercises/03_html/01_syntax/` directory. Navigate to this using the SSH Terminal, install the all the necessary `koa` packages and start the web server. If you navigate to the base route `/` you will see a screen full of text. ![the unformatted text](exercises/.images/chrome_07.png) @@ -90,7 +90,7 @@ Now you have mastered the basics of HTML markup we will look at one of the most ### 3.1 Routes -Every resource on the WWW (such as html documents and images) has a unique URL and so when we design our website we need to define these. In a website built using _NodeJS_ and _Koa_ these are known as **routes**. Start by locating the `exercises/02_html/03_hypermedia/` directory. Start the web server and open the `index.js` file. +Every resource on the WWW (such as html documents and images) has a unique URL and so when we design our website we need to define these. In a website built using _NodeJS_ and _Koa_ these are known as **routes**. Start by locating the `exercises/03_html/03_hypermedia/` directory. Start the web server and open the `index.js` file. 1. Some resources need to be directly accessible in the web browser (they are accessed either directly or loaded by the html web page). These need to have their own directly accessible URL. 1. One directory needs to be specified as being publicly available. In this example we have created a directory called `public/` From 7849d678c2a49fb2342af7d81151d316038619de Mon Sep 17 00:00:00 2001 From: "Mark Tyers (aa7401)" Date: Thu, 12 Sep 2019 11:17:18 +0100 Subject: [PATCH 3/6] moved a paragraph --- 03 HTML5.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/03 HTML5.md b/03 HTML5.md index 88c06459..d05d8c91 100644 --- a/03 HTML5.md +++ b/03 HTML5.md @@ -1,7 +1,7 @@ # Learning HTML5 -Before you start you need to pull any _upstream changes_. Detailed instructions can be found in the **Setup** lab. +Before you start you need to pull any _upstream changes_. Detailed instructions can be found in the **Setup** lab. You should get into the habit of doing this each time you sit down to work on your lab exercises as you will then be working on the latest versions of the files (with fewer bugs). In this worksheet you will be learning about the markup language HTML which is currently in version 5. The worksheet is split into five parts with the resources for each part in their own subdirectory. The `template.html` file contains a basic HTML5 template you will find useful when creating your own web pages. @@ -17,8 +17,6 @@ In this worksheet you will be learning about the markup language HTML which is c    └── template.html ``` -You should get into the habit of doing this each time you sit down to work on your lab exercises as you will then be working on the latest versions of the files (with fewer bugs). - ## 1 Syntax Lets take a look at some basic HTML syntax. Start by locating the `exercises/03_html/01_syntax/` directory. Navigate to this using the SSH Terminal, install the all the necessary `koa` packages and start the web server. If you navigate to the base route `/` you will see a screen full of text. From 9733cdd41862ebc9c20930a2939babf60caa8024 Mon Sep 17 00:00:00 2001 From: "Mark Tyers (aa7401)" Date: Thu, 12 Sep 2019 12:10:29 +0100 Subject: [PATCH 4/6] re-numbered sections --- 05 JavaScript.md | 83 +++++++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 33 deletions(-) diff --git a/05 JavaScript.md b/05 JavaScript.md index 3db5f45d..7a2e0cdd 100644 --- a/05 JavaScript.md +++ b/05 JavaScript.md @@ -1,8 +1,10 @@ -# Functions and Objects +# JavaScript Before you start you need to pull any _upstream changes_. Detailed instructions can be found in the **Setup** lab. +In this lab you will be exploring the JavaScript programming language. This will not cover programming fundamentals since you can already program in Python and/or C++ but will instead focus on the features of the language that differ from other languages you may be comfortable with. + ## 1 Functions In JavaScript, as in most other languages, code can be divided in to modular blocks called functions. Once defined, these can be called from other code. Data can be passed in the form of parameters and functions can return data back to the calling code. @@ -53,7 +55,7 @@ Open the `contact.js` script, implement the `validateEmail()` function and thoro ### 1.2 Function Expressions -Functions are a data type in JavaScript (they are objects but more on that in the next chapter). As such they can be stored in variables for later execution. Prior to ECMA6 they were declared using the `function` keyword like this: +Functions are a data type in JavaScript (they are objects but more on that later). As such they can be stored in variables for later execution. Prior to ECMA6 they were declared using the `function` keyword like this: ```javascript const remainder = function(dividend, divisor) { @@ -99,7 +101,7 @@ const sqr = num => num * num 4. Modify the function expression so that it can handle any number of string parameters (use a _rest parameter_). 5. Can you reduce this function expression to a single line (hint: explore using the [reduce function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) combined with the [ternary operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator))? -### 1.3 Callbacks +## 2 Callbacks Since JavaScript supports _first class functions_, we can use a function in any place where we could use a literal, object or variable. Open the `currency.js` script and look at line 17. As you can see the `request` object has a key called `get` that stores a function (we have already covered this). This takes two parameters: @@ -107,6 +109,10 @@ Since JavaScript supports _first class functions_, we can use a function in any 2. A function that will be called once the data has been retrived from the url. This was defined earlier in the script and takes 3 parameters. ```javascript +const printRates = (err, res, body) => { + const data = JSON.parse(body) + console.log(`for each EUR you will get ${data.rates[symbol]} ${symbol} today`) +} request.get(url, printRates) ``` @@ -116,27 +122,38 @@ NodeJS is a single-threaded event loop that processes queued events. This means Because callbacks are such a fundamental part of NodeJS you need to spend time to make sure you fully understand how they work. -#### 1.3.1 Using Anonymous Functions in Callbacks +#### 2.1 Using Anonymous Functions in Callbacks Although this code works, you will rarely see callbacks written in this manner. Creating a function literal is a bit clunky and we can clean up the code by simply passing an anonymous function. ```javascript request.get( url, (err, res, body) => { - // callback code goes here. + const data = JSON.parse(body) + console.log(`for each EUR you will get ${data.rates[symbol]} ${symbol} today`) }) ``` Take a few moments to make sure you fully understand the syntax, you will be seeing a lot of this over the next few weeks. -### 1.3.2 Test Your Understanding +### 2.1.1 Test Your Understanding + +You are now going to apply you knowledge of JavaScript callbacks by connecting to the [Open Weather API](https://openweathermap.org/api). Start by opening the `weather.js` file: + +1. Read through the code to make sure you understand how it works. +2. Register for an API key and add this to the script where indicated. +2. Run the script and check the output, can you explain the first two lines of output, why are the data types as shown? +3. Can you make sense of the other data? +3. Use the [Open Weather API](https://openweathermap.org/api) to retrieve and display the hourly forcast. + +## 2.2 Defining Functions with Callbacks -TODO +In the previous section you learned how to call pre-defined functions with callbacks. Now you will learn how to write your own functions that include callbacks. This is important since NodeJS has a single-threaded model and any activity that may take time to complete should never be in the main thread. By creating a function with a callback you can push the task onto its own thread and free up the main event thread. -## 2 Objects +## 3 Objects Lets start by creating an manipulating objects using **object literals**. Open the `employee.js` file, read through it and see if you can work out what it does. Now run it to see if you were correct. -### 2.1 Creating Object Literals +### 3.1 Creating Object Literals The simplest way to create new objects is by creating an _object literal_ which is defining an object and storing it in a variable in a similar way to how we created function literals earlier in the lab. You should open the `employee.js` file which contains the code. @@ -175,12 +192,12 @@ firstName! first-name ``` -#### 2.1.1 Test Your Understanding +#### 3.1.1 Test Your Understanding 1. Add a property called `gender` and assign a suitable String value. 2. Add a new property called `date of birth` that stores the year the person was born and assign a suitable value. -### 2.2 Retrieving Object Properties +### 3.2 Retrieving Object Properties Whilst it is possible (and useful) to log an entire object to the console, normally we would want to retrieve the values of specific properties, this is known as **destructuring** an object. @@ -209,7 +226,7 @@ const grade = employee.grade || 'A' This will retrieve the value of the grade property if defined and store it in the `const` variable. If this property is missing the `const` variable will contain the string `'A'`. -#### 2.2.1 Test Your Understanding +#### 3.2.1 Test Your Understanding Lets apply our knowledge of callbacks to implement a simple quotes tool. @@ -219,7 +236,7 @@ Lets apply our knowledge of callbacks to implement a simple quotes tool. 4. Create a loop to iterate through the array, printing the contents of each index. 5. Modify the code so that it only prints the quotes string (not the entire object). -#### 2.3.1 ECMA6 Object Destructuring +### 3.3 ECMA6 Object Destructuring In ECMA6 is is possible to extract multiple pieces of data into separate variables by destructuring using an _object pattern_. This is syntactically similar to creating object literals (see the example below). @@ -235,7 +252,7 @@ console.log(first) // prints 'Colin' console.log(dept) // prints 'Computing' ``` -### 2.3 Getters and Setters +### 3.4 Getters and Setters Most object properties are simple values and you can simply assign a value. Sometimes however properties need to be calculated. One solution is to store a function as one of the properties however we would need to call a function to retrieve the value: @@ -295,12 +312,12 @@ const employee = { employee.name = 'Micky Mouse' ``` -#### 2.3.1 Test Your Understanding +#### 3.4.1 Test Your Understanding 1. Print the person's details in an easy to understand sentence. 2. Add a getter to return the number of years the employee has been working for the company, you will need to round this down to a whole number. You should make use of one of the static methods of the built-in [Math](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math) object. -### 2.4 Modifying Objects +### 3.5 Modifying Objects Once an object has been created it can be modified in several ways. @@ -336,7 +353,7 @@ const employee = { delete employee.department ``` -### 2.5 Undefined Values +### 3.6 Undefined Values Undefined Objects @@ -357,13 +374,13 @@ const postCode = employee.address && employee.address.postCode console.log(postCode) // returns undefined ``` -#### 2.5.1 Test Your Understanding +#### 3.6.1 Test Your Understanding 1. Modify the code to handle bad data: 1. Remove the startYear property. 2. Set the startYear property to a String. -### 2.6 Object Prototypes +### 3.7 Object Prototypes All JavaScript object (such as String, Number, Array, etc.) inherit properties and methods from a **prototype**. This also applies to any new objects you create. Since JavaScript does not support _traditional_ classes, this becomes the way to add new functionality. Let's look at a simple example. @@ -385,15 +402,15 @@ There are a couple of important concepts here. 2. Inside the function we manipulate the `this` object which represents the value of the object. 1. Replace the `function() {}` construct with an arrow function. What happens when you run the script? -#### 2.6.1 Test Your Understanding +#### 3.7.1 Test Your Understanding 1. Extend the `Array` object by adding a function `toStr()` that takes an array and turns it into a string. You will need to use the [`Array.join()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join) function. -## 3 Object Constructors +## 4 Object Constructors As you have seen from the previous section, each object (String, Number, etc) has its own _prototype_, but what about the custom objects you created? It turns out that these also have a prototype, _Object_. Any functionality you add to this will get added to _all the objects in your application!_. To get round this problem NodeJS has the `new` keyword. When this is used we can isolate any changes to the targeted object. -### 3.1 Object Constructor Functions +### 4.1 Object Constructor Functions Until ECMA6, there wa a way to achieve this by using a **constructor function**. Whilst this is not now considered the optimal way to achieve our goal there are so many examples of this approach it is important you understand both the syntax and how it works. When we use this approach using the `new` keyword triggers four steps: @@ -423,7 +440,7 @@ console.log(nigel) Note that it is a convention that objects that can be used to create objects using the `new` keyword start with a capital letter. Also notice that when we print the object it clearly shows that it is an instance of `Person` and not `Object`. -### 3.2 Extending using Object Constructor Functions +### 4.2 Extending using Object Constructor Functions Whilst this syntax is not using traditional classes, one object can _extend_ another. This is best illustrated through the example below where we create another object called `Student`. @@ -442,7 +459,7 @@ console.log(anne) // Student { name: 'anne', startYear: 2019, years: 0, course: 'not enrolled' } ``` -### 3.3 ECMA6 Class Syntax +### 4.3 ECMA6 Class Syntax Whilst constructor functions are not particularly elegant they do provide a way to structure your objects efficiently. ECMA6 introduced a cleaner way to work with these using **classes**. Note that despite this looking like a (traditional) OOP language, remember it is really only a different syntax for constructor functions. Let's look at the previous example using the new syntax: @@ -488,7 +505,7 @@ class Student extends Person { } ``` -### 3.4 Static Members +### 4.4 Static Members Currently each instance of a prototype function is completely self-contained. What if we need to store data about the prototype function itself? In a traditional OOP language we would use static methods and the new ECMA `class` syntax allows us to do something similar by adding properties to the prototype function itself. We can also define static methods that can be called directly from the prototype function, see the example below. @@ -513,7 +530,7 @@ console.log(ECMA6Student.studentCount()) // prints '2' Notice that the static vsriable `count` is public (so the `studentCount()` method is somewhat superfluous in this example!). This highlights one of the limitations of JavaScript, the lack of a simple way to define private attributes (variables and methods). The next section goes into this in more detail and explains some workarounds (hacks) to get around this. -### 3.5 Handling Data Encapsulation +### 4.5 Handling Data Encapsulation In all of these objects all data is public (you can see the entire object by using `console.log()`). One of the weaknesses of NodeJS (and JavaScript in general) is that there is no clean way to _encapsulate_ data and make it hidden from the outside world. There are a number of techniques to get around this problem: @@ -524,24 +541,24 @@ In all of these objects all data is public (you can see the entire object by usi You should take time to understand the [pros and cons](https://2ality.com/2016/01/private-data-classes.html) of all four approaches. -### 3.6 Test Your Understanding +### 4.6 Test Your Understanding 1. Create a **constructor function** called `OldVehicle` that includes `make`, `model` and `price` information. Use this to create two vehicles of your choice. 2. Use this to create a second **constructor function** class called `OldPickup` that includes `payload` and `seats` fields and use this to create two pickup objects. 3. Now use the same information to create a class called `NewVehicle` and extend this to create a class called `NewPickup` and use this to create two or more pickup objects. 4. Add a static member to capture the total value of all the pickup sales and print this to the terminal. -## 4 RESTful APIs and JSON Data +## 5 JSON Data //TODO: write this section...! -### 4.1 JSON Data +### 5.1 JSON Data Show how objects can be turned into strings and saved. text data loaded and converted into a JavaScript object. -#### 4.1.1 Test Your Understanding +#### 5.1.1 Test Your Understanding -### 4.2 RESTful APIs +### 5.2 RESTful APIs Show how data can be retrieved from an API in JSON format. @@ -551,7 +568,7 @@ OMDB key: 220d2590 First task is for students to get an OMDB API key and paste it into the provided script. -### 4.3 Nested Callbacks +### 5.3 Nested Callbacks Use the same API and show that multiple steps cause nested callbacks and callback hell. @@ -570,7 +587,7 @@ Open the file `nestedCallbacks.js` which asks for a _base_ currency code then pr Callbacks are the simplest possible mechanism for asynchronous code in JavaScript. Unfortunately, raw callbacks sacrifice the control flow, exception handling, and function semantics familiar from synchronous code. -### 4.4 Test Your Knowledge +### 5.4 Test Your Knowledge The callbacks are already nested 3 deep. To test your knowledge of deeply nested callbacks you are going to create a script that has 6 levels of nested callbacks! From 783876cfae176b861c3065cbfbd6e2ff8a0c330d Mon Sep 17 00:00:00 2001 From: Mark Tyers Date: Thu, 12 Sep 2019 12:10:57 +0100 Subject: [PATCH 5/6] added callback examples --- exercises/01_setup/index.js | 1 + exercises/05_javascript/files.js | 20 ++++++++++++++++++++ exercises/05_javascript/messages.txt | 5 +++++ exercises/05_javascript/weather.js | 15 +++++++++++++++ 4 files changed, 41 insertions(+) create mode 100755 exercises/05_javascript/files.js create mode 100644 exercises/05_javascript/messages.txt create mode 100755 exercises/05_javascript/weather.js diff --git a/exercises/01_setup/index.js b/exercises/01_setup/index.js index 57bcaaae..ef00019f 100644 --- a/exercises/01_setup/index.js +++ b/exercises/01_setup/index.js @@ -1,3 +1,4 @@ +#!/usr/bin/env node 'use strict' diff --git a/exercises/05_javascript/files.js b/exercises/05_javascript/files.js new file mode 100755 index 00000000..ebdbfe33 --- /dev/null +++ b/exercises/05_javascript/files.js @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +'use strict' + +const fs = require('fs') + +function saveText(text, callback) { + try { + fs.appendFileSync('messages.txt', `${text}\n`, 'ascii') + const contents = fs.readFileSync('messages.txt', 'utf8') + callback(null, contents) + } catch(err) { + callback(err) + } +} + +saveText('Hello world!', (err, data) => { + if(err) console.log(err) + console.log(data) +}) diff --git a/exercises/05_javascript/messages.txt b/exercises/05_javascript/messages.txt new file mode 100644 index 00000000..9ed16b86 --- /dev/null +++ b/exercises/05_javascript/messages.txt @@ -0,0 +1,5 @@ +Hello world!Hello world!Hello world!text +text +text +Hello world! +Hello world! diff --git a/exercises/05_javascript/weather.js b/exercises/05_javascript/weather.js new file mode 100755 index 00000000..f139cc00 --- /dev/null +++ b/exercises/05_javascript/weather.js @@ -0,0 +1,15 @@ +#!/usr/bin/env node + +'use strict' + +const request = require('request') + +const url = 'https://api.openweathermap.org/data/2.5/weather?q=coventry,uk&appid=44c39f3fa462f86b3fc88f5678e5c5ff' + +request(url, (err, response, body) => { + if(err) console.log(err.message) + console.log(`the body variable contains a ${typeof body}`) + const data = JSON.parse(body) + console.log(`the data variable contains an ${typeof data}`) + console.log(data) +}) From 1c92266430add08e4e9e54a13f9db43d72ab9397 Mon Sep 17 00:00:00 2001 From: Mark Tyers Date: Thu, 12 Sep 2019 13:25:59 +0100 Subject: [PATCH 6/6] aded json section to lab --- .gitignore | 2 ++ 05 JavaScript.md | 69 +++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index f9196409..ae2fd49a 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ website.db # IDE setting files *.codio *.c9 + +messages.txt diff --git a/05 JavaScript.md b/05 JavaScript.md index 7a2e0cdd..c5633e8e 100644 --- a/05 JavaScript.md +++ b/05 JavaScript.md @@ -122,7 +122,7 @@ NodeJS is a single-threaded event loop that processes queued events. This means Because callbacks are such a fundamental part of NodeJS you need to spend time to make sure you fully understand how they work. -#### 2.1 Using Anonymous Functions in Callbacks +### 2.1 Using Anonymous Functions in Callbacks Although this code works, you will rarely see callbacks written in this manner. Creating a function literal is a bit clunky and we can clean up the code by simply passing an anonymous function. @@ -141,14 +141,22 @@ You are now going to apply you knowledge of JavaScript callbacks by connecting t 1. Read through the code to make sure you understand how it works. 2. Register for an API key and add this to the script where indicated. -2. Run the script and check the output, can you explain the first two lines of output, why are the data types as shown? -3. Can you make sense of the other data? -3. Use the [Open Weather API](https://openweathermap.org/api) to retrieve and display the hourly forcast. +3. Run the script and check the output, can you explain the first two lines of output, why are the data types as shown? +4. Can you make sense of the other data? +5. Use the [Open Weather API](https://openweathermap.org/api) to retrieve and display the hourly forcast. ## 2.2 Defining Functions with Callbacks In the previous section you learned how to call pre-defined functions with callbacks. Now you will learn how to write your own functions that include callbacks. This is important since NodeJS has a single-threaded model and any activity that may take time to complete should never be in the main thread. By creating a function with a callback you can push the task onto its own thread and free up the main event thread. +Start by opening the `files.js` script and study it carefully: + +1. Notice that we are reading and writing to files in the main thread! This would normally block the thread, slowing down the program execution. +2. Also notice that the reading and writing takes place in a function `savetext()` with a callback defined as its second parameter. +3. At the end of the `saveText()` function we execute the callback. +4. We can then call our `saveText()` function, passing an anonymous callback function as the second parameter, this is executed within the `saveText()` function. +5. The convention when defining functions that take a callback function is to define the error as the first parameter. + ## 3 Objects Lets start by creating an manipulating objects using **object literals**. Open the `employee.js` file, read through it and see if you can work out what it does. Now run it to see if you were correct. @@ -226,7 +234,52 @@ const grade = employee.grade || 'A' This will retrieve the value of the grade property if defined and store it in the `const` variable. If this property is missing the `const` variable will contain the string `'A'`. -#### 3.2.1 Test Your Understanding +### 3.3 JSON Data + +JSON (JavaScript Object Notation) is a standard text-based format to represent structured data. This is very useful as it means we can take any JavaScript object and convert it into a text string. This can then be saved to disk or posted to a web server, etc. It also means that you can take a JSON-formatted text string and convert it into a complex JavaScript object! + +#### 3.3.1 Parsing JSON Strings into Objects + +It is trivial to convert a JSON string into an object using the `JSON.parse()` function. Study the following code carefully: + +```javascript +const jsonstring = '{ "firstName": "Colin", "last name": "Stephen", "department": "Computing"}' +const employee = JSON.parse(jsonstring) +``` + +Notice that in a JSON string all the properties and values _must_ be enclosed in double-quotes. The constant `jsonstring` is a **String** but `employee` is a standard JavaScript **Object**. + +#### 3.3.2 Converting Objects into Strings + +In the same way that we can convert a JSON string into a JavaScript object we can also do the reverse. + +```javascript +const employee = { + firstName: 'Colin', + 'last name': 'Stephen', + 'department': 'Computing' +} +const jsonstring = JSON.stringify(employee) +console.log(jsonstring) +// { "firstName": "Colin", "last name": "Stephen", "department": "Computing"} +``` + +In this example `jsonstring` is a **String**. If we print out this string we will see that it contains a single line of text which can sometimes be hard to understand. If we want the string to be more readable we can pass another parameter. + +```javascript +const jsonstring = JSON.stringify(employee, null, 2) +/* +{ + "firstName": "Colin", + "last name": "Stephen", + "department": "Computing" +} +*? +``` + +This inserts newline and space characters to make the string more readable. The third parameter defines the level of indent (in spaces). + +#### 3.3.3 Test Your Understanding Lets apply our knowledge of callbacks to implement a simple quotes tool. @@ -548,15 +601,11 @@ You should take time to understand the [pros and cons](https://2ality.com/2016/0 3. Now use the same information to create a class called `NewVehicle` and extend this to create a class called `NewPickup` and use this to create two or more pickup objects. 4. Add a static member to capture the total value of all the pickup sales and print this to the terminal. -## 5 JSON Data - -//TODO: write this section...! -### 5.1 JSON Data Show how objects can be turned into strings and saved. text data loaded and converted into a JavaScript object. -#### 5.1.1 Test Your Understanding +### 5.1.1 Test Your Understanding ### 5.2 RESTful APIs