# notes

path: zk/Network_scanning.md
sortable_path: zkNetwork_scanning.md
title: Network scanning
lead: # Network scanning
checksum: eb7a61101a4e8fb6df7031b46992b7bc54dadb99e5895bfc7fcbd3cc6d9930ef
created: 2024-06-10 18:04:10.389369098+00:00
modified: 2024-06-12 17:30:30.934189688+00:00
body:
  # Network scanning

  ## List all connected devices on local WiFi network

  ```sh
  arp-scan --interface=wlan0 --localnet
  ```

  ## Scan subnet for all connected devices (in case hiding)

  ```sh
  nmap -sn 192.168.0.0/24
  ```

  ## Check DNS resolution

  ```sh
  dig google.com
  ```

  Key output:

  ```
  ;; Query time: 6 msec
  ;; SERVER: 192.168.0.4#53(192.168.0.4) (UDP)
  ;; WHEN: Wed Jun 12 18:27:27 BST 2024
  ;; MSG SIZE  rcvd: 55
  ```

raw_content:
  ---
  id: ippn
  title: Network scanning
  tags: [networks, procedural, Linux]
  created: Monday, June 10, 2024
  ---

  # Network scanning

  ## List all connected devices on local WiFi network

  ```sh
  arp-scan --interface=wlan0 --localnet
  ```

  ## Scan subnet for all connected devices (in case hiding)

  ```sh
  nmap -sn 192.168.0.0/24
  ```

  ## Check DNS resolution

  ```sh
  dig google.com
  ```

  Key output:

  ```
  ;; Query time: 6 msec
  ;; SERVER: 192.168.0.4#53(192.168.0.4) (UDP)
  ;; WHEN: Wed Jun 12 18:27:27 BST 2024
  ;; MSG SIZE  rcvd: 55
  ```

metadata:
  {"created":"Monday, June 10, 2024","id":"ippn","tags":["networks","procedural","Linux"],"title":"Network scanning"}


path: zk/Headless network setup.md
sortable_path: zkHeadless network setup.md
title: Headless network setup
lead: # Headless network setup
checksum: 78195b0784aa1d1c8256569e3cf8e63cccb43ce3054296ec65397190669b21cd
created: 2024-06-12 17:40:01.361581526+00:00
modified: 2024-06-12 17:48:06.368431989+00:00
body:
  # Headless network setup

  If you are using a headless system and you aren't using an ethernet connection,
  you face a chicken-egg issue of how to connect the device to WiFi via `ssh` when
  the device isn't yet on the network.

  You can get around this by saving a file called `wp_supplicant.conf` to the
  `/boot` directory of the device. This specifies the SSID name and password and
  will be used to auto-connect when the device boots.

  For example:

  ```
  country=GB
  ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
  update_config=1
  network={
       ssid="SKYVL7XP"
       scan_ssid=1
       psk="WIFI_PASSWORD"
       key_mgmt=WPA-PSK
  }
  ```

  ## Related notes

raw_content:
  ---
  id: hb10
  title: Headless network setup
  tags: [networks, Linux]
  created: Wednesday, June 12, 2024
  ---

  # Headless network setup

  If you are using a headless system and you aren't using an ethernet connection,
  you face a chicken-egg issue of how to connect the device to WiFi via `ssh` when
  the device isn't yet on the network.

  You can get around this by saving a file called `wp_supplicant.conf` to the
  `/boot` directory of the device. This specifies the SSID name and password and
  will be used to auto-connect when the device boots.

  For example:

  ```
  country=GB
  ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
  update_config=1
  network={
       ssid="SKYVL7XP"
       scan_ssid=1
       psk="WIFI_PASSWORD"
       key_mgmt=WPA-PSK
  }
  ```

  ## Related notes

metadata:
  {"created":"Wednesday, June 12, 2024","id":"hb10","tags":["networks","Linux"],"title":"Headless network setup"}


path: zk/Headless_network_setup.md
sortable_path: zkHeadless_network_setup.md
title: Headless network setup
lead: # Headless network setup
body:
  # Headless network setup


  ## Related notes

checksum: d001f4d7d4bce02fe22d4df9e9a43a8bc54143de004d63a5e83bcd799043b384
created: 2024-06-12 17:45:11.903958951+00:00
modified: 2024-06-12 17:40:01.359436753+00:00
metadata: {"created":"Wednesday, June 12, 2024","id":"hb10","tags":[],"title":"Headless network setup"}
raw_content:
  ---
  id: hb10
  title: Headless network setup
  tags: []
  created: Wednesday, June 12, 2024 
  ---
  # Headless network setup


  ## Related notes


path: zk/Set_DNS_settings.md
sortable_path: zkSet_DNS_settings.md
title: Set DNS settings
lead: # Set DNS settings
checksum: 041d180765010673945ef5e9f2c044d8a05823cde14a102bf3531ff0bb3a720a
created: 2024-06-12 17:45:11.913843931+00:00
modified: 2024-06-12 17:39:46.862282491+00:00
body:
  # Set DNS settings

  ## Change the default DNS server

  On Arch and most modern Linux distributions domain name resolution is handled
  via the `systemd-resolved` #systemd configuration.

  Within the system systemd files this will be handled in
  `/systemd/network/wired.network` or `systemd/network/wlan.network` files etc.

  In the file below I have turned of DHCP routing and specified the address of my
  Pi-hole device to handle domain name resolution:

  ```
  #wlan.network

  [Match]
  Name=wl*

  [Link]
  RequiredForOnline=routable

  [Network]
  DHCP=yes
  DNS=192.168.0.4
  MulticastDNS=yes

  [DHCPv4]
  UseDNS=no
  RouteMetric=600

  [IPv6AcceptRA]
  RouteMetric=600

  ```

  ## Related notes

raw_content:
  ---
  id: 2w0e
  title: Set DNS settings
  tags: [Linux, networks]
  created: Wednesday, June 12, 2024
  ---

  # Set DNS settings

  ## Change the default DNS server

  On Arch and most modern Linux distributions domain name resolution is handled
  via the `systemd-resolved` #systemd configuration.

  Within the system systemd files this will be handled in
  `/systemd/network/wired.network` or `systemd/network/wlan.network` files etc.

  In the file below I have turned of DHCP routing and specified the address of my
  Pi-hole device to handle domain name resolution:

  ```
  #wlan.network

  [Match]
  Name=wl*

  [Link]
  RequiredForOnline=routable

  [Network]
  DHCP=yes
  DNS=192.168.0.4
  MulticastDNS=yes

  [DHCPv4]
  UseDNS=no
  RouteMetric=600

  [IPv6AcceptRA]
  RouteMetric=600

  ```

  ## Related notes

metadata:
  {"created":"Wednesday, June 12, 2024","id":"2w0e","tags":["Linux","networks"],"title":"Set DNS settings"}


path: zk/5__Integrating_the_Mongo_database.md
sortable_path: zk5__Integrating_the_Mongo_database.md
title: Creating a RESTful API: Integrating the database
checksum: 538034760405536a2f4949cde906dd4398f0f43c0e8e59a51357aae3c5fe19f0
created: 2024-06-16 17:06:08.163986495+00:00
modified: 2024-06-15 10:04:45.832445734+00:00
metadata: {"tags":["node-js","REST","APIs","mongo-db","databases"]}
lead:
  So far we have set up the application and an `/api/courses` route which handles
  requests for RESTful API operations on a local array of course objects. We now
  want to have the endpoints operate on a MongoDB `courses` collection rather than
  the array.

body:
  So far we have set up the application and an `/api/courses` route which handles
  requests for RESTful API operations on a local array of course objects. We now
  want to have the endpoints operate on a MongoDB `courses` collection rather than
  the array.

  ## Set-up

  We will follow the routine for establishing a MongoDB instance as detailed in
  [my notes](Connect_to_Mongo_database.md) on Mongo:

  - [Create MongoDB database](Create_Mongo_database.md)
  - [Connect to MongoDB database](Connect_to_Mongo_database.md)

  Our `index.js` now looks like the following:

  ```js
  // index.js

  // Connect to database
  mongoose
    .connect("mongodb://127.0.0.1/playground")
    .then(() => console.log("Connected to MongoDB"))
    .catch((err) => console.error(err));

  app.use(express.json());

  // Link to `courses` route which contains our REST request handlers for this part of the API
  app.use("/api/courses", courses);
  ```

  ## Integrating Mongo with our our `courses` module

  ### Create the schema

  Now we go the router module for `courses` and start to use Mongoose, defining
  our `Course` schema:

  ```diff
  // index.js

  // Connect to database
  mongoose
    .connect("mongodb://127.0.0.1/playground")
    .then(() => console.log("Connected to MongoDB"))
    .catch((err) => console.error(err));

  app.use(express.json());

  // Link to `courses` route which contains our REST request handlers for this part of the API
  app.use("/api/courses", courses);

  + const courseSchema = new mongoose.Schema({
  +  name: {type: String, required: true, minlength: 5, maxlength: 255},
  +  author: String,
  +  tags: [String],
  +  data: {type: Date, default: Date.now}, // if unspecified, entry will default to current date
  +  isPublished: Boolean,
  + });

  ```

  ### Create a model

  ```diff
  const courseSchema = new mongoose.Schema({
    name: {type: String, required: true, minlength: 5, maxlength: 255},
    author: String,
    tags: [String],
    data: {type: Date, default: Date.now}, // if unspecified, entry will default to current date
    isPublished: Boolean,
   });

  + const Course = new mongoose.model('Course', courseSchema);
  ```

  With this established we can remove our local array as we are ready to start
  getting our data from the database:

  ```diff
  const Course = mongoose.model('Course', courseSchema);

  - const courses = [
  -  {
  -    id: 1,
  -    name: "First course",
  -  },
  -  ...
  -];
  ```

  We could actually simplify the syntax here and combine our schema and model
  declaration into a single block:

  ```js
  const Course = mongoose.model(
    "Course",
    new mongoose.Schema({
      name: { type: String, required: true, minlength: 5, maxlength: 255 },
      author: String,
      tags: [String],
      data: { type: Date, default: Date.now }, // if unspecified, entry will default to current date
      isPublished: Boolean,
    })
  );
  ```

  > N.B In a real project we wouldn't keep our models in the same file as our
  > handlers. We would keep them in the dedicated `/models/` directory. We should
  > stick to the single responsibility principle and keep `/routes/` for API
  > handlers and `/model/` for schema declarations and models.

  ## Rewriting the REST handlers

  Now we need to rewrite our RESTful request handlers so that the data is sourced
  from and added to the database. We will mainly be using the Mongo syntax defined
  at [Querying a collection](Querying_a_Mongo_collection.md) and
  [Adding documents to a collection](Adding_documents_to_a_Mongo_collection.md).
  We will also keep API validation within the `/model/` file.

  ### GET

  Instead of simply returning the array, we use the Mongoose `find` method.

  ```diff
  - router.get("/", (req, res) => {
  -  res.send(courses);
   });

  + router.get("/", async (res, res) => {
  +  const courses = await Courses.find();
    res.send(courses)
  })
  ```

  ### POST

  Now we make our new course an instance of the `Courses` model:

  ```js
  // Original formulation

  router.post("/", (req, res) => {
  -  const course = {
  -    id: courses.length + 1,
  -    name: req.body.name,
  -  };
    courses.push(course);
    res.send(course);
  });
  ```

  ```diff
  router.post("/", async (req, res) => {
  +  let course = new Course({ // make new course instance of Course model
  -   id: courses.length + 1, // not needed as DB automatically adds an id
      name: req.body.name,
    });
  - courses.push(course); // not pushing to the array anymore
  + await course.save() // save to Mongo
    res.send(course);
  });

  ```

  ### PUT

  When updating a value in the database we are going to use the
  [query-first](Update_a_Mongo_document.md#query-first-document-update)
  approach to updating a Mongo document.

  ```jsconst courseSchema = new mongoose.Schema({
    name: {type: String, required: true, minlength: 5, maxlength: 255},
    author: String,
    tags: [String],
    data: {type: Date, default: Date.now}, // if unspecified, entry will default to current date
    isPublished: Boolean,
   });
  router.put("/:id", (req, res) => {
    const course = courses.find((c) => c.id === parseInt(req.params.id));

    if (!course)
      return res.status(404).send("A course with the given ID was not found");

    const { error } = validateCourse(req.body);
    if (error)
      return error.details.map((joiErr) => res.status(400).send(joiErr.message));
  const courseSchema = new mongoose.Schema({
    name: {type: String, required: true, minlength: 5, maxlength: 255},
    author: String,
    tags: [String],
    data: {type: Date, default: Date.now}, // if unspecified, entry will default to current date
    isPublished: Boolean,
   });
    course.name = req.body.name;
    res.send(course);
  });
  ```

  ```diff
  router.put("/:id", async (req, res) => {
  - const course = courses.find((c) => c.id === parseInt(req.params.id));
   const { error } = validateCourse(req.body);
   if (!course) return res.status(404).send("A course with the given ID was not found");
  + const updatedCourse = await Course.findByIdAndUpdate(req.params.id,
  +  { name: req.body.name },
  +  { new: true}
  + )

  -   if (error)
  -   return error.details.map((joiErr) => res.status(400).send(joiErr.message));
  - })

  - course.name = req.body.name;
    res.send(course);
  ```

  ### DELETE

  ```js
  router.delete("/:id", (req, res) => {
    const course = courses.find((c) => c.id === parseInt(req.params.id));
    if (!course)
      return res.status(404).send("A course with the given ID was not found");

    courses.indexOf(course);
    courses.splice(index, 1);
    res.send(course);
  });
  ```

  ```diff

  router.delete("/:id", async (req, res) => {
   const courseToDelete = await Course.findByIdAndRemove(req.params.id)

   if (!course) return res.status(404).send("A course with the given ID was not found");

  - courses.indexOf(course);
  - courses.splice(index, 1);

  res.send(course);
  })
  ```

raw_content:
  ---
  tags:
    - node-js
    - REST
    - APIs
    - mongo-db
    - databases
  ---

  # Creating a RESTful API: Integrating the database

  So far we have set up the application and an `/api/courses` route which handles
  requests for RESTful API operations on a local array of course objects. We now
  want to have the endpoints operate on a MongoDB `courses` collection rather than
  the array.

  ## Set-up

  We will follow the routine for establishing a MongoDB instance as detailed in
  [my notes](Connect_to_Mongo_database.md) on Mongo:

  - [Create MongoDB database](Create_Mongo_database.md)
  - [Connect to MongoDB database](Connect_to_Mongo_database.md)

  Our `index.js` now looks like the following:

  ```js
  // index.js

  // Connect to database
  mongoose
    .connect("mongodb://127.0.0.1/playground")
    .then(() => console.log("Connected to MongoDB"))
    .catch((err) => console.error(err));

  app.use(express.json());

  // Link to `courses` route which contains our REST request handlers for this part of the API
  app.use("/api/courses", courses);
  ```

  ## Integrating Mongo with our our `courses` module

  ### Create the schema

  Now we go the router module for `courses` and start to use Mongoose, defining
  our `Course` schema:

  ```diff
  // index.js

  // Connect to database
  mongoose
    .connect("mongodb://127.0.0.1/playground")
    .then(() => console.log("Connected to MongoDB"))
    .catch((err) => console.error(err));

  app.use(express.json());

  // Link to `courses` route which contains our REST request handlers for this part of the API
  app.use("/api/courses", courses);

  + const courseSchema = new mongoose.Schema({
  +  name: {type: String, required: true, minlength: 5, maxlength: 255},
  +  author: String,
  +  tags: [String],
  +  data: {type: Date, default: Date.now}, // if unspecified, entry will default to current date
  +  isPublished: Boolean,
  + });

  ```

  ### Create a model

  ```diff
  const courseSchema = new mongoose.Schema({
    name: {type: String, required: true, minlength: 5, maxlength: 255},
    author: String,
    tags: [String],
    data: {type: Date, default: Date.now}, // if unspecified, entry will default to current date
    isPublished: Boolean,
   });

  + const Course = new mongoose.model('Course', courseSchema);
  ```

  With this established we can remove our local array as we are ready to start
  getting our data from the database:

  ```diff
  const Course = mongoose.model('Course', courseSchema);

  - const courses = [
  -  {
  -    id: 1,
  -    name: "First course",
  -  },
  -  ...
  -];
  ```

  We could actually simplify the syntax here and combine our schema and model
  declaration into a single block:

  ```js
  const Course = mongoose.model(
    "Course",
    new mongoose.Schema({
      name: { type: String, required: true, minlength: 5, maxlength: 255 },
      author: String,
      tags: [String],
      data: { type: Date, default: Date.now }, // if unspecified, entry will default to current date
      isPublished: Boolean,
    })
  );
  ```

  > N.B In a real project we wouldn't keep our models in the same file as our
  > handlers. We would keep them in the dedicated `/models/` directory. We should
  > stick to the single responsibility principle and keep `/routes/` for API
  > handlers and `/model/` for schema declarations and models.

  ## Rewriting the REST handlers

  Now we need to rewrite our RESTful request handlers so that the data is sourced
  from and added to the database. We will mainly be using the Mongo syntax defined
  at [Querying a collection](Querying_a_Mongo_collection.md) and
  [Adding documents to a collection](Adding_documents_to_a_Mongo_collection.md).
  We will also keep API validation within the `/model/` file.

  ### GET

  Instead of simply returning the array, we use the Mongoose `find` method.

  ```diff
  - router.get("/", (req, res) => {
  -  res.send(courses);
   });

  + router.get("/", async (res, res) => {
  +  const courses = await Courses.find();
    res.send(courses)
  })
  ```

  ### POST

  Now we make our new course an instance of the `Courses` model:

  ```js
  // Original formulation

  router.post("/", (req, res) => {
  -  const course = {
  -    id: courses.length + 1,
  -    name: req.body.name,
  -  };
    courses.push(course);
    res.send(course);
  });
  ```

  ```diff
  router.post("/", async (req, res) => {
  +  let course = new Course({ // make new course instance of Course model
  -   id: courses.length + 1, // not needed as DB automatically adds an id
      name: req.body.name,
    });
  - courses.push(course); // not pushing to the array anymore
  + await course.save() // save to Mongo
    res.send(course);
  });

  ```

  ### PUT

  When updating a value in the database we are going to use the
  [query-first](Update_a_Mongo_document.md#query-first-document-update)
  approach to updating a Mongo document.

  ```jsconst courseSchema = new mongoose.Schema({
    name: {type: String, required: true, minlength: 5, maxlength: 255},
    author: String,
    tags: [String],
    data: {type: Date, default: Date.now}, // if unspecified, entry will default to current date
    isPublished: Boolean,
   });
  router.put("/:id", (req, res) => {
    const course = courses.find((c) => c.id === parseInt(req.params.id));

    if (!course)
      return res.status(404).send("A course with the given ID was not found");

    const { error } = validateCourse(req.body);
    if (error)
      return error.details.map((joiErr) => res.status(400).send(joiErr.message));
  const courseSchema = new mongoose.Schema({
    name: {type: String, required: true, minlength: 5, maxlength: 255},
    author: String,
    tags: [String],
    data: {type: Date, default: Date.now}, // if unspecified, entry will default to current date
    isPublished: Boolean,
   });
    course.name = req.body.name;
    res.send(course);
  });
  ```

  ```diff
  router.put("/:id", async (req, res) => {
  - const course = courses.find((c) => c.id === parseInt(req.params.id));
   const { error } = validateCourse(req.body);
   if (!course) return res.status(404).send("A course with the given ID was not found");
  + const updatedCourse = await Course.findByIdAndUpdate(req.params.id,
  +  { name: req.body.name },
  +  { new: true}
  + )

  -   if (error)
  -   return error.details.map((joiErr) => res.status(400).send(joiErr.message));
  - })

  - course.name = req.body.name;
    res.send(course);
  ```

  ### DELETE

  ```js
  router.delete("/:id", (req, res) => {
    const course = courses.find((c) => c.id === parseInt(req.params.id));
    if (!course)
      return res.status(404).send("A course with the given ID was not found");

    courses.indexOf(course);
    courses.splice(index, 1);
    res.send(course);
  });
  ```

  ```diff

  router.delete("/:id", async (req, res) => {
   const courseToDelete = await Course.findByIdAndRemove(req.params.id)

   if (!course) return res.status(404).send("A course with the given ID was not found");

  - courses.indexOf(course);
  - courses.splice(index, 1);

  res.send(course);
  })
  ```


path: zk/Adding_documents_to_a_Mongo_collection.md
sortable_path: zkAdding_documents_to_a_Mongo_collection.md
title: Adding documents to a collection
checksum: c8d62e948fd02c6e17f06f9f86160fc06534336683a11c46439528ba0a6a6a41
created: 2024-06-16 17:06:08.252028118+00:00
modified: 2024-06-15 09:57:02.990710464+00:00
metadata: {"tags":["mongo-db","node-js","mongoose","databases"]}
lead:
  We have our database (`playground`) and collection (`courses`) established. We
  now need to add documents to our collection. We will do this via a function
  since this will be an asynchronous process:

body:
  We have our database (`playground`) and collection (`courses`) established. We
  now need to add documents to our collection. We will do this via a function
  since this will be an asynchronous process:

  ```js
  const pythonCourse = new Course({
    name: "Python Course",
    author: "Terry Ogleton",
    tags: ["python", "backend"],
    isPublished: true,
  });

  async function addCourseDocToDb(courseDocument) {
    try {
      const result = await courseDocument.save();
      console.log(result);
    } catch (err) {
      console.error(err.message);
    }
  }

  addCourseDocToDb(nodeCourse);
  ```

  When we run this, we call the `save` method on the Mongoose schema. We will then
  have the Mongo document outputted to the console:

  ```
  {
    name: 'Python Course',
    author: 'Terry Ogleton',
    tags: [ 'python' ],
    isPublished: true,
    _id: new ObjectId("62f4ac989d2fec2f01596b9b"),
    date: 2022-08-11T07:15:36.978Z,
    __v: 0
  }
  ```

  This will also be reflected in Compass:

  ![](/img/mongo-doc-added.png)

raw_content:
  ---
  tags:
    - mongo-db
    - node-js
    - mongoose
    - databases
  ---

  # Adding documents to a collection

  We have our database (`playground`) and collection (`courses`) established. We
  now need to add documents to our collection. We will do this via a function
  since this will be an asynchronous process:

  ```js
  const pythonCourse = new Course({
    name: "Python Course",
    author: "Terry Ogleton",
    tags: ["python", "backend"],
    isPublished: true,
  });

  async function addCourseDocToDb(courseDocument) {
    try {
      const result = await courseDocument.save();
      console.log(result);
    } catch (err) {
      console.error(err.message);
    }
  }

  addCourseDocToDb(nodeCourse);
  ```

  When we run this, we call the `save` method on the Mongoose schema. We will then
  have the Mongo document outputted to the console:

  ```
  {
    name: 'Python Course',
    author: 'Terry Ogleton',
    tags: [ 'python' ],
    isPublished: true,
    _id: new ObjectId("62f4ac989d2fec2f01596b9b"),
    date: 2022-08-11T07:15:36.978Z,
    __v: 0
  }
  ```

  This will also be reflected in Compass:

  ![](/img/mongo-doc-added.png)


path: zk/Application_state_management_with_React_hooks.md
sortable_path: zkApplication_state_management_with_React_hooks.md
title: Application state management
checksum: da892726957c790ec1bce967b56554aea92feeb3b52aed639a7ae0dae3d3a10e
created: 2024-06-16 17:06:08.257788818+00:00
modified: 2024-06-15 10:16:42.954140592+00:00
metadata: {"tags":["javascript","react"]}
lead:
  Although [React_useReducer](React_useReducer.md) and [React_useContext](React_useContext.md) have
  many sound use cases by themselves, when they are combined they offer a way to
  acheive a system of global state management, without utilising third-party
  libraries like Redux.

body:
  Although [React_useReducer](React_useReducer.md) and [React_useContext](React_useContext.md) have
  many sound use cases by themselves, when they are combined they offer a way to
  acheive a system of global state management, without utilising third-party
  libraries like Redux.

  ## Requirements

  The Context API combined with a reducer addresses the following needs:

  - be able to consume global state from anywhere in the component hierarchy
    without prop-drilling
  - update global state from within child components from anywhere in the
    component hierarchy
  - access, maintain and update complex structured data (arrays/objects) not just
    single values, as global state

  ## Implementation

  In essence the approach is as follows:

  - Create a context provider that houses the global state object
  - Attach this state to a reducer function that operates on the state object
    through dispatch methods

  First off, our initial state and overall state object:

  ```js
  const initialState = {
    count: 0,
  };
  ```

  Next, we create our context. This is what we will invoke when we want to consume
  our state.

  ```js
  export const CounterContext = React.createContext({});
  ```

  Now we need a reducer that will handle the state updates. We will just use the
  same setup as we used in the example of
  [React_useReducer](React_useReducer.md#refining-the-syntax):

  ```js
  function reducer(state, action) {
    switch (action.type) {
      case "increase":
        return { ...state, counter: state.counter + 1 };
        break;
      case "decrease":
        return { ...state, counter: state.counter - 1 };
        break;
      case "increase_by_payload":
        return { ...state, counter: state.counter + action.payload };
      default:
        throw new Error();
    }
    return newState;
  }
  ```

  Finally, we need to make a provider as a top-level component that receives the
  reducer's `state` and `dispatch` methods as props:

  ```js
  export const CounterProvider = ({children}) => {
      // We pass our reducer function and initial state to useReducer as params
      const [state, dispatch] = React.useReducer(reducer, initialState)

      // We create our provider and pass the reducer state and update method as props. This is the provider to the CounterContext consumer
      <CounterContext.Provider value={{state, dispatch}}>
          {children}
      </CounterContext.Provider>
  }
  ```

  Now whenever we want to consume or update our global state, we can invoke the
  context within a lower-level component, for example:

  ```js
  const {state, dispatch} = useContext(CounterContext);

  dispatch({
      type 'increase_by_payload',
      payload: 4
  })

  console.log(state.counter) // 4

  ```

raw_content:
  ---
  tags:
    - javascript
    - react
  ---

  # Application state management

  Although [React_useReducer](React_useReducer.md) and [React_useContext](React_useContext.md) have
  many sound use cases by themselves, when they are combined they offer a way to
  acheive a system of global state management, without utilising third-party
  libraries like Redux.

  ## Requirements

  The Context API combined with a reducer addresses the following needs:

  - be able to consume global state from anywhere in the component hierarchy
    without prop-drilling
  - update global state from within child components from anywhere in the
    component hierarchy
  - access, maintain and update complex structured data (arrays/objects) not just
    single values, as global state

  ## Implementation

  In essence the approach is as follows:

  - Create a context provider that houses the global state object
  - Attach this state to a reducer function that operates on the state object
    through dispatch methods

  First off, our initial state and overall state object:

  ```js
  const initialState = {
    count: 0,
  };
  ```

  Next, we create our context. This is what we will invoke when we want to consume
  our state.

  ```js
  export const CounterContext = React.createContext({});
  ```

  Now we need a reducer that will handle the state updates. We will just use the
  same setup as we used in the example of
  [React_useReducer](React_useReducer.md#refining-the-syntax):

  ```js
  function reducer(state, action) {
    switch (action.type) {
      case "increase":
        return { ...state, counter: state.counter + 1 };
        break;
      case "decrease":
        return { ...state, counter: state.counter - 1 };
        break;
      case "increase_by_payload":
        return { ...state, counter: state.counter + action.payload };
      default:
        throw new Error();
    }
    return newState;
  }
  ```

  Finally, we need to make a provider as a top-level component that receives the
  reducer's `state` and `dispatch` methods as props:

  ```js
  export const CounterProvider = ({children}) => {
      // We pass our reducer function and initial state to useReducer as params
      const [state, dispatch] = React.useReducer(reducer, initialState)

      // We create our provider and pass the reducer state and update method as props. This is the provider to the CounterContext consumer
      <CounterContext.Provider value={{state, dispatch}}>
          {children}
      </CounterContext.Provider>
  }
  ```

  Now whenever we want to consume or update our global state, we can invoke the
  context within a lower-level component, for example:

  ```js
  const {state, dispatch} = useContext(CounterContext);

  dispatch({
      type 'increase_by_payload',
      payload: 4
  })

  console.log(state.counter) // 4

  ```


path: zk/Basic_prop_passing_in_React.md
sortable_path: zkBasic_prop_passing_in_React.md
title: Test: Basic prop passing
lead:
  ```js
  import { render, screen } from "@testing-library/react";

checksum: 993345f8e5dee18e7890d64e30484fee3dc60f56195cf3f5155e23ba6479b4ee
created: 2024-06-16 17:06:08.298039624+00:00
modified: 2024-03-27 10:45:52.500191986+00:00
metadata: {"tags":["javascript","react","testing"]}
body:
  ```js
  import { render, screen } from "@testing-library/react";

  describe("<CertificateHtml />", () => {
    it("should render the values passed as props", () => {
      // Arrange:
      const stub = {
        titleOfActivityOrProgramme: "Filming",
        nameOfDepartment: "The film department",
      };

      // Act:
      render(<CertificateHtml {...stub} />);

      // Assert:
      expect(screen.getByText("Filming")).toBeInTheDocument();
      expect(screen.getByText("The film department")).toBeInTheDocument();
    });
  });
  ```

  Or, loop:

  ```js
  for (const entry of Object.values(stub)) {
    expect(screen.getByText(entry)).toBeInTheDocument();
  }
  ```

raw_content:
  ---
  tags:
    - javascript
    - react
    - testing
  ---

  # Test: Basic prop passing

  ```js
  import { render, screen } from "@testing-library/react";

  describe("<CertificateHtml />", () => {
    it("should render the values passed as props", () => {
      // Arrange:
      const stub = {
        titleOfActivityOrProgramme: "Filming",
        nameOfDepartment: "The film department",
      };

      // Act:
      render(<CertificateHtml {...stub} />);

      // Assert:
      expect(screen.getByText("Filming")).toBeInTheDocument();
      expect(screen.getByText("The film department")).toBeInTheDocument();
    });
  });
  ```

  Or, loop:

  ```js
  for (const entry of Object.values(stub)) {
    expect(screen.getByText(entry)).toBeInTheDocument();
  }
  ```


path: zk/Built_in_React_hooks.md
sortable_path: zkBuilt_in_React_hooks.md
title: Typing built-in hooks
lead: ## `useState`
checksum: 16efeb56bb48c15813a9a8693b69ac5532ab281fbd7acbd3166d82ee5e1b721f
created: 2024-06-16 17:06:08.407038333+00:00
modified: 2024-06-15 10:07:23.685272098+00:00
metadata: {"tags":["typescript","react"]}
body:
  ## `useState`

  ```tsx
  const [amount, setAmount] = useState<number | string>(3);
  ```

  ### With a ustom type

  ```tsx
  interface IState {
    people: IPerson[];
  }

  interface IPerson {
    name: string;
    age: number;
  }

  const [people, setPeople] = useState<IState>({});

  // Alternative declaration

  interface IState {
    people: {
      name: string;
      age: number;
    }[];
  }

  const [people, setPeople] = useState<IState["people"]>({});
  ```

  ## `useReducer`

  Mostly the same. They key thing to type is the reducer function itself. You
  don't need to type the intitial state unless it is a pre-existing type, you can
  just use type assertion:

  ```jsx
  interface IAction {
    | { type: "increment"; payload: number }
    | { type: "decrement"; payload: string };
  }

  const initialState = { count: 0 };

  function reducer(state: typeof initialState, action: IAction) {
    switch (action.type) {
      case "increment":
        return { count: state.count + action.payload };
      case "decrement":
        return { count: state.count - Number(action.payload) };
      default:
        throw new Error();
    }
  }
  ```

  Then the syntax is as normal, i.e:

  ```js
  const [state, dispatch] = useReducer(reducer, initialState);
  ```

  ## `useEffect`

  > Limited potential for typing here as this hook does not return a value. See if
  > there is useful inferred typing from use and update.

  ## `useContext`

  We can use generics but mostly this is untyped:

  ```jsx
  type Theme = "light" | "dark";
  const ThemeContext = createContext < Theme > "dark";

  const App = () => (
    <ThemeContext.Provider value="dark">
      <MyComponent />
    </ThemeContext.Provider>
  );

  const MyComponent = () => {
    const theme = useContext(ThemeContext);
    return <div>The theme is {theme}</div>;
  };
  ```

  ## `useCallback` / `useMemo`

  You must only type the parameters that are passed to the callback, the return
  value will be inferred.

raw_content:
  ---
  tags:
    - typescript
    - react
  ---

  # Typing built-in hooks

  ## `useState`

  ```tsx
  const [amount, setAmount] = useState<number | string>(3);
  ```

  ### With a ustom type

  ```tsx
  interface IState {
    people: IPerson[];
  }

  interface IPerson {
    name: string;
    age: number;
  }

  const [people, setPeople] = useState<IState>({});

  // Alternative declaration

  interface IState {
    people: {
      name: string;
      age: number;
    }[];
  }

  const [people, setPeople] = useState<IState["people"]>({});
  ```

  ## `useReducer`

  Mostly the same. They key thing to type is the reducer function itself. You
  don't need to type the intitial state unless it is a pre-existing type, you can
  just use type assertion:

  ```jsx
  interface IAction {
    | { type: "increment"; payload: number }
    | { type: "decrement"; payload: string };
  }

  const initialState = { count: 0 };

  function reducer(state: typeof initialState, action: IAction) {
    switch (action.type) {
      case "increment":
        return { count: state.count + action.payload };
      case "decrement":
        return { count: state.count - Number(action.payload) };
      default:
        throw new Error();
    }
  }
  ```

  Then the syntax is as normal, i.e:

  ```js
  const [state, dispatch] = useReducer(reducer, initialState);
  ```

  ## `useEffect`

  > Limited potential for typing here as this hook does not return a value. See if
  > there is useful inferred typing from use and update.

  ## `useContext`

  We can use generics but mostly this is untyped:

  ```jsx
  type Theme = "light" | "dark";
  const ThemeContext = createContext < Theme > "dark";

  const App = () => (
    <ThemeContext.Provider value="dark">
      <MyComponent />
    </ThemeContext.Provider>
  );

  const MyComponent = () => {
    const theme = useContext(ThemeContext);
    return <div>The theme is {theme}</div>;
  };
  ```

  ## `useCallback` / `useMemo`

  You must only type the parameters that are passed to the callback, the return
  value will be inferred.


path: zk/Child_to_parent_data_flow_in_React.md
sortable_path: zkChild_to_parent_data_flow_in_React.md
title: Child to parent data flow
checksum: 63856c6f093fdced5941549b4f278df726d284bb3eea79e182d5c3c8b0af24dd
created: 2024-06-16 17:06:08.483513137+00:00
modified: 2024-06-15 10:08:01.602615809+00:00
metadata: {"tags":["javascript","react"]}
lead:
  Despite React having a uni-directional, downwards data-flow, it is sometimes
  necessary to pass events and data from a child back up to the parent. This need
  can arise when you want to modularize functionality within a child component
  rather than have everything happening in the parent, and you don't want to use a
  common shared higher context.

body:
  Despite React having a uni-directional, downwards data-flow, it is sometimes
  necessary to pass events and data from a child back up to the parent. This need
  can arise when you want to modularize functionality within a child component
  rather than have everything happening in the parent, and you don't want to use a
  common shared higher context.

  For the example we will use the standard click incrementer.

  We have a counter on the parent that is updated in response to a click event in
  the child component.

  Our parent component is `App` and the child component is `Child`

  ```jsx
  export default function App() {
    const [count, setCount] = useState(0);
    return (
      <>
        <p>{count}</p>
        <Child count={count} setCount={setCount} />
      </>
    );
  }

  const Child = ({ count, setCount }) => {
    return <button onClick={() => setCount(count + 1)}>Increment</button>;
  };
  ```

  So the overall state and updater function exists on the parent. The child is
  able to access this state by virtue of receiving `{count, setCount}` as props.
  It can therefore manipulate this state and have it be reflected in the parent.

  It is not necessary to pass the state variable every time. You could just pass
  the updater. We have passed the `count` variable here because the child needs
  access to the current value, in order to be able to increment it.

raw_content:
  ---
  tags:
    - javascript
    - react
  ---

  # Child to parent data flow

  Despite React having a uni-directional, downwards data-flow, it is sometimes
  necessary to pass events and data from a child back up to the parent. This need
  can arise when you want to modularize functionality within a child component
  rather than have everything happening in the parent, and you don't want to use a
  common shared higher context.

  For the example we will use the standard click incrementer.

  We have a counter on the parent that is updated in response to a click event in
  the child component.

  Our parent component is `App` and the child component is `Child`

  ```jsx
  export default function App() {
    const [count, setCount] = useState(0);
    return (
      <>
        <p>{count}</p>
        <Child count={count} setCount={setCount} />
      </>
    );
  }

  const Child = ({ count, setCount }) => {
    return <button onClick={() => setCount(count + 1)}>Increment</button>;
  };
  ```

  So the overall state and updater function exists on the parent. The child is
  able to access this state by virtue of receiving `{count, setCount}` as props.
  It can therefore manipulate this state and have it be reflected in the parent.

  It is not necessary to pass the state variable every time. You could just pass
  the updater. We have passed the `count` variable here because the child needs
  access to the current value, in order to be able to increment it.


path: zk/Comparing_React_classes_to_hooks.md
sortable_path: zkComparing_React_classes_to_hooks.md
title: Comparing class components to hook-based components
lead:
  We will look at the same component written with hooks and classes. Both use this
  child component:

checksum: 5ed406f78142c4075d1118c27ed9b0cf5d84269988210b765ffd1386709946c1
created: 2024-06-16 17:06:08.559532679+00:00
modified: 2024-06-15 10:07:39.545555372+00:00
metadata: {"tags":["javascript","react"]}
body:
  We will look at the same component written with hooks and classes. Both use this
  child component:

  ```jsx
  const CounterBox = (props) => {
    return <div className="output">{props.counterValue}</div>;
  };
  ```

  ## Class component

  ```jsx
  import CounterBox from "./CounterBox";

  class CounterClass extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        counterValue: 0,
      };
    }

    addOne() {
      this.setState({
        counterValue: this.state.counterValue + 1,
      });
    }

    render() {
      return (
        <React.Fragment>
          <button onClick={() => this.addOne()}>Add One</button>
          <CounterBox counterValue={this.state.counterValue} />
        </React.Fragment>
      );
    }
  }
  ```

  ## Hook version

  ```jsx
  import React, { useState } from "react";
  import CounterBox from "./CounterBox";

  function CounterHook() {
    const [counter, setCounter] = useState(0);
    const handleClick = () => setCounter(counter + 1);
    return (
      <React.Fragment>
        <button onClick={handleClick}>Add One</button>
        <CounterBox counterValue={counter}></CounterBox>
      </React.Fragment>
    );
  }
  ```

  ## Main differences

  - Obviously with hooks we use a function, not a class. We can therefore think of
    them as **simple components** that are able to handle state as well as props.
  - We have written the hook as a declared function but we could just as easily
    write it as a function expression or arrow function.
  - With the class, the state versioning is managed via the following properties
    on the `React.Component` class: `this.state` (start state) and `this.setState`
    (the change).
  - In both cases the function that actually creates the change is handled via an
    arrow function. With the hook we use the customary name `handleClick` .

  - The same process is managed in the hook via the `useState()` method. We
    effectively set 'before' and 'after' destructured variables on this method:

    ```jsx
    const [counter, setCounter] = useState(0);

    // Schematically:
    const [val, setVal] = useState(initialVal);
    ```

  ## Binding with class component state

  In the class component example we use an inline arrow function to execute
  `addOne()` however the official way to do it is to bind the event via the
  constructor method to avoid the problems created by `this` scope in classes.
  Using arrows is mostly fine and is less verbose, but it is important to
  understand the 'official' approach.

  The way to write the state change in this way is:

  ```jsx
  class CounterClass extends React.Component{
    constructor(props){
      super(props);
  		this.state = { counterValue: 0};
      this.handleClick = this.handleClick.bind(this); // bind the click to the class scope
    }

    handleClick(event){
      this.setState({
              counterValue: this.state.counterValue + 1;
      });
    }

    render(){
      return (
        <button type="button"
        onClick={this.handleClick}> // reference the class scope with `this`
        Click Me
        </button>
  			<CounterBox counterValue={this.state.counterValue}></CounterBox>
      );
    }
  }
  ```

  ## How hooks improve on class components

  - State, when managed via hooks can be easily decoupled from a specific
    component and reused elsewhere. This also means it can be tested separately
    from any specific component where it is applied. This is much harder to do
    with classes which are closely entangled with the non-state aspects of a
    component through `this` and binding:

    > With Hooks, you can extract stateful logic from a component so it can be
    > tested independently and reused. Hooks allow you to reuse stateful logic
    > without changing your component hierarchy. This makes it easy to share Hooks
    > among many components or with the community.

  - Hooks simplify lifestyle methods and the use of `componentDidMount` etc
    through the `useEffect` hook
  - Classes and `this` are confusing generally. Functions are easier to grasp and
    read.

  ## Relation to function components

  You can think of hooks as function components (previously known as stateless
  components) plus state. Previously function components were 'dumb' components.
  That is, they didn't allow for state management and generally used for layout.
  They could receive data as props but not state. This changes with hooks: you can
  add state to functions and no longer need to use classes exclusively for state.
  In fact you no longer need to use classes at all, unless you want to.

  > The stateful portion of a function component must be placed before the
  > `return()` statement in the function.

raw_content:
  ---
  tags:
    - javascript
    - react
  ---

  # Comparing class components to hook-based components

  We will look at the same component written with hooks and classes. Both use this
  child component:

  ```jsx
  const CounterBox = (props) => {
    return <div className="output">{props.counterValue}</div>;
  };
  ```

  ## Class component

  ```jsx
  import CounterBox from "./CounterBox";

  class CounterClass extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        counterValue: 0,
      };
    }

    addOne() {
      this.setState({
        counterValue: this.state.counterValue + 1,
      });
    }

    render() {
      return (
        <React.Fragment>
          <button onClick={() => this.addOne()}>Add One</button>
          <CounterBox counterValue={this.state.counterValue} />
        </React.Fragment>
      );
    }
  }
  ```

  ## Hook version

  ```jsx
  import React, { useState } from "react";
  import CounterBox from "./CounterBox";

  function CounterHook() {
    const [counter, setCounter] = useState(0);
    const handleClick = () => setCounter(counter + 1);
    return (
      <React.Fragment>
        <button onClick={handleClick}>Add One</button>
        <CounterBox counterValue={counter}></CounterBox>
      </React.Fragment>
    );
  }
  ```

  ## Main differences

  - Obviously with hooks we use a function, not a class. We can therefore think of
    them as **simple components** that are able to handle state as well as props.
  - We have written the hook as a declared function but we could just as easily
    write it as a function expression or arrow function.
  - With the class, the state versioning is managed via the following properties
    on the `React.Component` class: `this.state` (start state) and `this.setState`
    (the change).
  - In both cases the function that actually creates the change is handled via an
    arrow function. With the hook we use the customary name `handleClick` .

  - The same process is managed in the hook via the `useState()` method. We
    effectively set 'before' and 'after' destructured variables on this method:

    ```jsx
    const [counter, setCounter] = useState(0);

    // Schematically:
    const [val, setVal] = useState(initialVal);
    ```

  ## Binding with class component state

  In the class component example we use an inline arrow function to execute
  `addOne()` however the official way to do it is to bind the event via the
  constructor method to avoid the problems created by `this` scope in classes.
  Using arrows is mostly fine and is less verbose, but it is important to
  understand the 'official' approach.

  The way to write the state change in this way is:

  ```jsx
  class CounterClass extends React.Component{
    constructor(props){
      super(props);
  		this.state = { counterValue: 0};
      this.handleClick = this.handleClick.bind(this); // bind the click to the class scope
    }

    handleClick(event){
      this.setState({
              counterValue: this.state.counterValue + 1;
      });
    }

    render(){
      return (
        <button type="button"
        onClick={this.handleClick}> // reference the class scope with `this`
        Click Me
        </button>
  			<CounterBox counterValue={this.state.counterValue}></CounterBox>
      );
    }
  }
  ```

  ## How hooks improve on class components

  - State, when managed via hooks can be easily decoupled from a specific
    component and reused elsewhere. This also means it can be tested separately
    from any specific component where it is applied. This is much harder to do
    with classes which are closely entangled with the non-state aspects of a
    component through `this` and binding:

    > With Hooks, you can extract stateful logic from a component so it can be
    > tested independently and reused. Hooks allow you to reuse stateful logic
    > without changing your component hierarchy. This makes it easy to share Hooks
    > among many components or with the community.

  - Hooks simplify lifestyle methods and the use of `componentDidMount` etc
    through the `useEffect` hook
  - Classes and `this` are confusing generally. Functions are easier to grasp and
    read.

  ## Relation to function components

  You can think of hooks as function components (previously known as stateless
  components) plus state. Previously function components were 'dumb' components.
  That is, they didn't allow for state management and generally used for layout.
  They could receive data as props but not state. This changes with hooks: you can
  add state to functions and no longer need to use classes exclusively for state.
  In fact you no longer need to use classes at all, unless you want to.

  > The stateful portion of a function component must be placed before the
  > `return()` statement in the function.


path: zk/Complete_Mongo_example.md
sortable_path: zkComplete_Mongo_example.md
title: MongoDB connection, set-up and data query: complete example
lead:
  ```js
  const mongoose = require("mongoose");

checksum: 5a56f5101e268df3d5310e77625532af679c2435d466d4e303ab8fa316dcff9a
created: 2024-06-16 17:06:08.563957305+00:00
modified: 2024-06-15 09:57:16.934300579+00:00
metadata: {"tags":["mongo-db","node-js","mongoose","databases"]}
body:
  ```js
  const mongoose = require("mongoose");

  mongoose..connect("mongodb://127.0.0.1/[databse_name]");

  const courseSchema = new mongoose.Schema({
      name: String,
      author: String,
      tags: [String],
      data: Date,
      isPublished: Boolean,
      price: Number
  })

  const Course = mongoose.model("Course", courseSchema);

  async function getCourses(){
      return await Course
          .find({isPublished: true, tags: "backend"})
          .sort({name: 1})
          .select({name: 1, author: 1});
  }
  ```

raw_content:
  ---
  tags:
    - mongo-db
    - node-js
    - mongoose
    - databases
  ---

  # MongoDB connection, set-up and data query: complete example

  ```js
  const mongoose = require("mongoose");

  mongoose..connect("mongodb://127.0.0.1/[databse_name]");

  const courseSchema = new mongoose.Schema({
      name: String,
      author: String,
      tags: [String],
      data: Date,
      isPublished: Boolean,
      price: Number
  })

  const Course = mongoose.model("Course", courseSchema);

  async function getCourses(){
      return await Course
          .find({isPublished: true, tags: "backend"})
          .sort({name: 1})
          .select({name: 1, author: 1});
  }
  ```


path: zk/Components_props_hooks_in_React.md
sortable_path: zkComponents_props_hooks_in_React.md
title: Components and props with hooks
lead: As of React 16.8 a class component can be expressed using a function-based hook.
checksum: 15c018061a8e397cfea50f3d2534a8030f03d46576d2586db7e574ba8cff0847
created: 2024-06-16 17:06:08.570896311+00:00
modified: 2024-06-15 10:07:41.832262871+00:00
metadata: {"tags":["javascript","react"]}
body:
  As of React 16.8 a class component can be expressed using a function-based hook.

  A class component:

  ```jsx
  class Welcome extends React.Component {
    render() {
      return <h1>Hello, {this.props.name}</h1>;
    }
  }
  ```

  The same component expressed as a hook:

  ```jsx
  function Welcome(props) {
    return <h1>Hello, {props.name}</h1>;
  }
  ```

  To output this component we use the same standard JSX syntax and pass the prop
  as an attribute of the JSX element:

  ```jsx
  <Welcome name="Thomas" />
  ```

  ## How hooks are rendered

  1. We call `ReactDOM.render()` with the `<Welcome name="Thomas" />` element.
     (This would typically be nested within a root `App` component; it wouldn't be
     directly passed to the parent render function.)
  2. React calls the `Welcome` component with `{name: 'Thomas'}` as the props.
  3. Our `Welcome` component returns a `<h1>Hello, Thomas</h1>` element as the
     result.
  4. React DOM efficiently updates the DOM to match `<h1>Hello, Thomas</h1>`.

  ## Function components must be pure functions

  > All React components must act like pure functions with respect to their props

  This means that functions should not attempt to change the inputs they receive
  as parameters. They must always return the same result for the same inputs:

  ```jsx
  function sum(a, b) {
    return a + b;
  }
  ```

  ```jsx
  function withdraw(account, amount) {
    account.total -= amount;
  }
  ```

  The reason for this is that **props are read-only** and we pass props to
  function components.

  We change components by using state, not by mutating props. This is consistent
  with React's
  [principle of the immutability of elements](Elements-992594b9cd2e483c85cddddffeb16f11).

raw_content:
  ---
  tags:
    - javascript
    - react
  ---

  # Components and props with hooks

  As of React 16.8 a class component can be expressed using a function-based hook.

  A class component:

  ```jsx
  class Welcome extends React.Component {
    render() {
      return <h1>Hello, {this.props.name}</h1>;
    }
  }
  ```

  The same component expressed as a hook:

  ```jsx
  function Welcome(props) {
    return <h1>Hello, {props.name}</h1>;
  }
  ```

  To output this component we use the same standard JSX syntax and pass the prop
  as an attribute of the JSX element:

  ```jsx
  <Welcome name="Thomas" />
  ```

  ## How hooks are rendered

  1. We call `ReactDOM.render()` with the `<Welcome name="Thomas" />` element.
     (This would typically be nested within a root `App` component; it wouldn't be
     directly passed to the parent render function.)
  2. React calls the `Welcome` component with `{name: 'Thomas'}` as the props.
  3. Our `Welcome` component returns a `<h1>Hello, Thomas</h1>` element as the
     result.
  4. React DOM efficiently updates the DOM to match `<h1>Hello, Thomas</h1>`.

  ## Function components must be pure functions

  > All React components must act like pure functions with respect to their props

  This means that functions should not attempt to change the inputs they receive
  as parameters. They must always return the same result for the same inputs:

  ```jsx
  function sum(a, b) {
    return a + b;
  }
  ```

  ```jsx
  function withdraw(account, amount) {
    account.total -= amount;
  }
  ```

  The reason for this is that **props are read-only** and we pass props to
  function components.

  We change components by using state, not by mutating props. This is consistent
  with React's
  [principle of the immutability of elements](Elements-992594b9cd2e483c85cddddffeb16f11).


path: zk/Conditionals_in_Bash.md
sortable_path: zkConditionals_in_Bash.md
title: Conditionals in Bash
lead: ## If statements
checksum: fdcef36604a1998318aad2344da29e3528c8ba744128a50ebf65c5b70bdba92e
created: 2024-06-16 17:06:08.588965949+00:00
modified: 2024-03-27 10:45:52.500191986+00:00
metadata: {"tags":["shell"]}
body:
  ## If statements

  - Conditional blocks start with `if` and end with the inversion `fi` (this is a
    common syntactic pattern in bash)
  - The conditional expression must be placed in square brackets with spaces
    either side. The spaces matter: if you omit them, the code will not run
  - We designate the code to run when the conditional is met with `then`
  - We can incorporate else if logic with `elif`

  ## Basic example

  ```bash
  if [ -e $var ]; then
    # Do something
  else
    # Do something else
  fi
  ```

  ## If, else

  ```bash
  if [ "$myMove" -eq "$opponentMove" ]; then
      (( totalScore+=myMove+3 ))
    elif [ $absDiff -eq 2 ] && [ "$myMove" -gt "$opponentMove" ]; then
      (( totalScore+=myMove))
    elif [ $absDiff -eq 2 ] && [ "$opponentMove" -gt "$myMove" ]; then
      (( totalScore+=myMove+6))
    elif [ $absDiff -eq 1 ] && [ "$opponentMove" -gt "$myMove" ]; then
      (( totalScore+=myMove))
    elif [ $absDiff -eq 1 ] && [ "$myMove" -gt "$opponentMove" ]; then
      (( totalScore+=myMove+6))
    fi
  ```

  ## Nested conditionals

  ```bash
  if [[ "$line" =~ ^$ ]]; then
    if [[ "$runningTotal" -gt "$highest" ]]; then
      (( highest=runningTotal ))
    fi
    # Reset running sum
    (( runningTotal=0 ))
  fi
  ```

raw_content:
  ---
  tags:
    - shell
  ---

  # Conditionals in Bash

  ## If statements

  - Conditional blocks start with `if` and end with the inversion `fi` (this is a
    common syntactic pattern in bash)
  - The conditional expression must be placed in square brackets with spaces
    either side. The spaces matter: if you omit them, the code will not run
  - We designate the code to run when the conditional is met with `then`
  - We can incorporate else if logic with `elif`

  ## Basic example

  ```bash
  if [ -e $var ]; then
    # Do something
  else
    # Do something else
  fi
  ```

  ## If, else

  ```bash
  if [ "$myMove" -eq "$opponentMove" ]; then
      (( totalScore+=myMove+3 ))
    elif [ $absDiff -eq 2 ] && [ "$myMove" -gt "$opponentMove" ]; then
      (( totalScore+=myMove))
    elif [ $absDiff -eq 2 ] && [ "$opponentMove" -gt "$myMove" ]; then
      (( totalScore+=myMove+6))
    elif [ $absDiff -eq 1 ] && [ "$opponentMove" -gt "$myMove" ]; then
      (( totalScore+=myMove))
    elif [ $absDiff -eq 1 ] && [ "$myMove" -gt "$opponentMove" ]; then
      (( totalScore+=myMove+6))
    fi
  ```

  ## Nested conditionals

  ```bash
  if [[ "$line" =~ ^$ ]]; then
    if [[ "$runningTotal" -gt "$highest" ]]; then
      (( highest=runningTotal ))
    fi
    # Reset running sum
    (( runningTotal=0 ))
  fi
  ```


path: zk/Connect_to_Mongo_database.md
sortable_path: zkConnect_to_Mongo_database.md
title: Connect to a database with Mongoose
checksum: 7aaf3990da7ec46f0171cfe1671c406ad4f29d136007bff56c9e4ad840e092fa
created: 2024-06-16 17:06:08.594665135+00:00
modified: 2024-06-15 09:57:45.698162691+00:00
metadata: {"tags":["mongo-db","node-js","mongoose","databases"]}
lead:
  Now that we have installed and configured MongoDB, we need to connect to it via
  Node.js. Mongoose is a simple API for interacting with a Mongo database via
  Node.

body:
  Now that we have installed and configured MongoDB, we need to connect to it via
  Node.js. Mongoose is a simple API for interacting with a Mongo database via
  Node.

  With Mongoose installed we can connect to a database. We don't have any Mongo
  databases yet beyond the defaults but the following Mongoose connection logic
  will create and connect to a new database called `playground`:

  Providing the Mongo server is running (execture `mongod`), we will see the
  confirmation message in the console.

  ```js
  mongoose
    .connect("mongodb://127.0.0.1/playground")
    .then(() => console.log("Connected to MongoDB"))
    .catch((err) => console.error(err));
  ```

raw_content:
  ---
  tags:
    - mongo-db
    - node-js
    - mongoose
    - databases
  ---

  # Connect to a database with Mongoose

  Now that we have installed and configured MongoDB, we need to connect to it via
  Node.js. Mongoose is a simple API for interacting with a Mongo database via
  Node.

  With Mongoose installed we can connect to a database. We don't have any Mongo
  databases yet beyond the defaults but the following Mongoose connection logic
  will create and connect to a new database called `playground`:

  Providing the Mongo server is running (execture `mongod`), we will see the
  confirmation message in the console.

  ```js
  mongoose
    .connect("mongodb://127.0.0.1/playground")
    .then(() => console.log("Connected to MongoDB"))
    .catch((err) => console.error(err));
  ```


path: zk/Controlled_components_in_React.md
sortable_path: zkControlled_components_in_React.md
title: Controlled components
lead: Controlled components relate to how you use forms in React.
checksum: af81e879e3f02c89c3466db77f21fa436c84f9a15d6ac37d6c6bafade97c566a
created: 2024-06-16 17:06:08.609508629+00:00
modified: 2024-03-27 10:45:52.500191986+00:00
metadata: {"tags":["javascript","react"]}
body:
  Controlled components relate to how you use forms in React.

  You can use standard form HTML within a React component but applying React state
  to the form via controlled components gives you greater power over what you do
  with the inputs and how you handle the data that is received.

  Standard HTML forms have a separate state from the rest of the document object
  and this is highly mutable. It can send requests to a server and reload the
  page. This mutability can obviously interfere with the state you maintain in
  your React components; this is why it is best to manage form state along with
  React state.

  We can combine the two [native HTML form state and React state] by making the
  React state be the “single source of truth”. Then the React component that
  renders a form also controls what happens in that form on subsequent user input.
  An input form element whose value is controlled by React in this way is called a
  “controlled component”.

raw_content:
  ---
  tags:
    - javascript
    - react
  ---

  # Controlled components

  Controlled components relate to how you use forms in React.

  You can use standard form HTML within a React component but applying React state
  to the form via controlled components gives you greater power over what you do
  with the inputs and how you handle the data that is received.

  Standard HTML forms have a separate state from the rest of the document object
  and this is highly mutable. It can send requests to a server and reload the
  page. This mutability can obviously interfere with the state you maintain in
  your React components; this is why it is best to manage form state along with
  React state.

  We can combine the two [native HTML form state and React state] by making the
  React state be the “single source of truth”. Then the React component that
  renders a form also controls what happens in that form on subsequent user input.
  An input form element whose value is controlled by React in this way is called a
  “controlled component”.


path: zk/Create_Mongo_database.md
sortable_path: zkCreate_Mongo_database.md
title: Creating a MongoDB database
lead: First create a directory for the database and set permissions:
checksum: a56970bff12ebf7528c38b17562308601f88cd30e75003021a128d7cfcee43ac
created: 2024-06-16 17:06:08.613468221+00:00
modified: 2024-06-15 09:59:15.773144522+00:00
metadata: {"tags":["mongo-db","node-js","mongoose","databases"]}
body:
  First create a directory for the database and set permissions:

  ```bash
  $ mkdir /data/db
  $ sudo chown -R `id -un` /data/db
  ```

  Then start the Mongo daemon

  ```bash
  mongod
  ```

  This will run continuously in the terminal and should say somewhere that it is
  waiting for connections on port `27017`. This command must be executed before
  you run any backend that interacts with the Mongo database.

  ## MongoDB Compass

  _Compass_ is a graphical interface for viewing and interacting with the data in
  your Mongo database. It will automatically load to the default Mongo port:
  `27017`.

  ![](/img/mongo-compass.png)

raw_content:
  ---
  tags:
    - mongo-db
    - node-js
    - mongoose
    - databases
  ---

  # Creating a MongoDB database

  First create a directory for the database and set permissions:

  ```bash
  $ mkdir /data/db
  $ sudo chown -R `id -un` /data/db
  ```

  Then start the Mongo daemon

  ```bash
  mongod
  ```

  This will run continuously in the terminal and should say somewhere that it is
  waiting for connections on port `27017`. This command must be executed before
  you run any backend that interacts with the Mongo database.

  ## MongoDB Compass

  _Compass_ is a graphical interface for viewing and interacting with the data in
  your Mongo database. It will automatically load to the default Mongo port:
  `27017`.

  ![](/img/mongo-compass.png)


path: zk/Creating_a_Mongo_schema_and_model.md
sortable_path: zkCreating_a_Mongo_schema_and_model.md
title: Creating a schema and model
lead: ## Schema
checksum: 8d1a9ab7816f21fb90420c49d1e20350e44e054dd06f880e69970db173517a4b
created: 2024-06-16 17:06:08.62560156+00:00
modified: 2024-06-15 10:03:20.357575648+00:00
metadata: {"tags":["mongo-db","node-js","mongoose","databases"]}
body:
  ## Schema

  In order start adding
  [collections and documents](MongoDB_Introduction.md) to our database,
  we use Mongoose's **schema** structure. (This is specific to Mongoose and is not
  a structure that is a part of Mongo in general.)

  We use a schema to define the shape of documents in a MongoDB collection. To do
  this we instantiate an instance of the Mongoose `Schema` class and set our
  properties:

  ### Creating a schema

  ```js
  const courseSchema = new mongoose.Schema({
    name: { type: String, required: true, minlength: 5, maxlength: 255 },
    author: String,
    tags: [String],
    data: { type: Date, default: Date.now }, // if unspecified, entry will default to current date
    isPublished: Boolean,
  });
  ```

  > This is similar to declaring a type or interface in TypeScript

  #### Available data types

  The following data types are available:

  - `String`
  - `Number`
  - `Boolean`
  - `Array`
  - `Date`
  - `Buffer`
  - `ObjectID` (for UUIDs)

  > Note that we set our validation criteria as the second property for each
  > schema value. There is more info info on validation in a
  > [separate entry](Validating_Mongoose_schemas.md);

  ## Models

  Once we have established our schema we can then create a **model** of it. A
  model is basically a class representation of the interface we define in the
  schema:

  ```js
  const Course = mongoose.model("Course", courseSchema);
  ```

  Now we can start adding specific courses as documents to our collection. We do
  this by referring to the model, i.e.

  ```js
  const course = new Course({
    name: "Node.js Course",
    author: "Ozzy Osbourne",
    tags: ["node", "backend"],
    isPublished: true,
  });
  ```

  ![](/img/mongoose-hierarchy.svg)

  ## Outcome

  Having created a database, connected to it with Mongoose, and created a model we
  will see our collection reflected in Compass:

  ![](img/../../../img/mongo-collection.png)

raw_content:
  ---
  tags:
    - mongo-db
    - node-js
    - mongoose
    - databases
  ---

  # Creating a schema and model

  ## Schema

  In order start adding
  [collections and documents](MongoDB_Introduction.md) to our database,
  we use Mongoose's **schema** structure. (This is specific to Mongoose and is not
  a structure that is a part of Mongo in general.)

  We use a schema to define the shape of documents in a MongoDB collection. To do
  this we instantiate an instance of the Mongoose `Schema` class and set our
  properties:

  ### Creating a schema

  ```js
  const courseSchema = new mongoose.Schema({
    name: { type: String, required: true, minlength: 5, maxlength: 255 },
    author: String,
    tags: [String],
    data: { type: Date, default: Date.now }, // if unspecified, entry will default to current date
    isPublished: Boolean,
  });
  ```

  > This is similar to declaring a type or interface in TypeScript

  #### Available data types

  The following data types are available:

  - `String`
  - `Number`
  - `Boolean`
  - `Array`
  - `Date`
  - `Buffer`
  - `ObjectID` (for UUIDs)

  > Note that we set our validation criteria as the second property for each
  > schema value. There is more info info on validation in a
  > [separate entry](Validating_Mongoose_schemas.md);

  ## Models

  Once we have established our schema we can then create a **model** of it. A
  model is basically a class representation of the interface we define in the
  schema:

  ```js
  const Course = mongoose.model("Course", courseSchema);
  ```

  Now we can start adding specific courses as documents to our collection. We do
  this by referring to the model, i.e.

  ```js
  const course = new Course({
    name: "Node.js Course",
    author: "Ozzy Osbourne",
    tags: ["node", "backend"],
    isPublished: true,
  });
  ```

  ![](/img/mongoose-hierarchy.svg)

  ## Outcome

  Having created a database, connected to it with Mongoose, and created a model we
  will see our collection reflected in Compass:

  ![](img/../../../img/mongo-collection.png)


path: zk/Custom_React_hook_examples.md
sortable_path: zkCustom_React_hook_examples.md
title: Custom hook examples
lead: ## Determine viewport width
checksum: 9b615de532028e7bc353d190dec415144439d7fbf9432311fa8b2121f3ac65c9
created: 2024-06-16 17:06:08.646830362+00:00
modified: 2024-06-15 10:07:55.872513534+00:00
metadata: {"tags":["javascript","react"]}
body:
  ## Determine viewport width

  ### Hook

  ```js
  // useViewportWidth.js
  import { useEffect, useState } from "react";

  export default function (viewportWidth) {
    const [matchesViewportWidth, setMatchesViewportWidth] = useState(false);

    useEffect(() => {
      const handleResize = () =>
        window.innerWidth < viewportWidth
          ? setMatchesViewportWidth(true)
          : setMatchesViewportWidth(false);

      window.addEventListener("resize", handleResize);

      // Call on initialization to determine initial width
      handleResize();

      // Clean-up listener to prevent memory leaks
      return () => window.removeEventListener("resize", handleResize);
    }, [viewportWidth]);

    return matchesViewportWidth;
  }
  ```

  ### Unit test

  ```js
  import useViewportWidth from "./useViewportWidth";
  import { fireEvent } from "@testing-library/react";
  import { act } from "react-dom/test-utils";
  import { renderHook } from "@testing-library/react-hooks";

  describe("useViewportWidth", () => {
    it("returns `true` when window resized to mobile viewport width", () => {
      // Arrange
      const { result } = renderHook(() => useViewportWidth(768));

      // Act
      act(() => {
        window.innerWidth = 500;
        fireEvent(window, new Event("resize"));
      });

      // Assert
      expect(result.current).toBe(true);
    });

    it("returns `false` when window resized to width greater than mobile viewport", () => {
      // Arrange
      const { result } = renderHook(() => useViewportWidth(768));

      // Act
      act(() => {
        window.innerWidth = 1058;
        fireEvent(window, new Event("resize"));
      });

      // Assert
      expect(result.current).toBe(false);
    });
  })``;
  ```

raw_content:
  ---
  tags:
    - javascript
    - react
  ---

  # Custom hook examples

  ## Determine viewport width

  ### Hook

  ```js
  // useViewportWidth.js
  import { useEffect, useState } from "react";

  export default function (viewportWidth) {
    const [matchesViewportWidth, setMatchesViewportWidth] = useState(false);

    useEffect(() => {
      const handleResize = () =>
        window.innerWidth < viewportWidth
          ? setMatchesViewportWidth(true)
          : setMatchesViewportWidth(false);

      window.addEventListener("resize", handleResize);

      // Call on initialization to determine initial width
      handleResize();

      // Clean-up listener to prevent memory leaks
      return () => window.removeEventListener("resize", handleResize);
    }, [viewportWidth]);

    return matchesViewportWidth;
  }
  ```

  ### Unit test

  ```js
  import useViewportWidth from "./useViewportWidth";
  import { fireEvent } from "@testing-library/react";
  import { act } from "react-dom/test-utils";
  import { renderHook } from "@testing-library/react-hooks";

  describe("useViewportWidth", () => {
    it("returns `true` when window resized to mobile viewport width", () => {
      // Arrange
      const { result } = renderHook(() => useViewportWidth(768));

      // Act
      act(() => {
        window.innerWidth = 500;
        fireEvent(window, new Event("resize"));
      });

      // Assert
      expect(result.current).toBe(true);
    });

    it("returns `false` when window resized to width greater than mobile viewport", () => {
      // Arrange
      const { result } = renderHook(() => useViewportWidth(768));

      // Act
      act(() => {
        window.innerWidth = 1058;
        fireEvent(window, new Event("resize"));
      });

      // Assert
      expect(result.current).toBe(false);
    });
  })``;
  ```


path: zk/Custom_types_in_TypeScript.md
sortable_path: zkCustom_types_in_TypeScript.md
title: Custom types
checksum: a31b1826fb6403da8b4a14f78beff6d2cc7d8b419f90d09d50660904af44a159
created: 2024-06-16 17:06:08.651591046+00:00
modified: 2024-03-27 10:45:52.500191986+00:00
metadata: {"tags":["typescript"]}
lead:
  Objects and [classes](Classes.md) are where TypeScript becomes most useful and
  powerful. In TypeScript, objects and classes are by definition custom types.

body:
  Objects and [classes](Classes.md) are where TypeScript becomes most useful and
  powerful. In TypeScript, objects and classes are by definition custom types.

  When typing objects, you do not write the types alongside the actual data as you
  would with primitive types, classes and functions. Instead you write a custom
  type which is a type-annotated object. This is then applied to the object or
  class, where you create instances that **match the shape** of the custom
  declaration.

  So say we have this object:

  ```js
  const age = {
    name: "Thomas",
    yearOfBirth: 1988,
    currentYear: 2021,
    ageNow: function () {
      return this.currentYear - this.yearOfBirth;
    },
  };
  ```

  We could write this as type with the following:

  ```ts
  let Age: {
    name: string;
    yearOfBirth: number;
    currentYear: number;
    ageNow: () => number;
  };
  ```

  (We use `:` because we are declaring a type not intialising a value of the
  type.)

  We could now re-write the first `age` object as an object of type `Age` :

  ```tsx
  let thomas: typeof Age;

  thomas = {
    name: "Thomas",
    yearOfBirth: 1988,
    currentYear: 2021,
    ageNow: function () {
      return this.currentYear - this.yearOfBirth;
    },
  };
  ```

  In practice, defining the type and then asserting that a new variable is of this
  type and then initialising it is rather long-winded. It is better practice to
  simplify the process by creating a **type alias**.

  ```tsx
  type Age = {
    name: string;
    yearOfBirth: number;
    currentYear: number;
    ageNow(): number; // we type the method on the basis of the value it returns
  };
  ```

  We could then create objects based on this:

  ```tsx
  const thomas: Age = {
    name: "Thomas",
    yearOfBirth: 1988,
    currentYear: 2021,
    ageNow: function () {
      return this.currentYear - this.yearOfBirth;
    },
  };
  ```

  Note that we pass in `:Age` as our type declaration, using the custom type in
  the same way as we would use `:string` or `number[]` . We can now use this
  custom type as a type annotation anywhere we use type annotations; it can be
  used exactly the same way as a primitive type in our code.

  `Age` is an alias for the type that `thomas` conforms to.

  The benefit is that TS will correct you if:

  - attempt to assign a type to a value that does not match the custom type
    declaration (for instance: assigning a string value to a property you have
    typed as number)
  - attempt to add a property that is not specified in the custom type declaration

  Although you can subsequently _extend_ the custom type (detailed below).

  ## Duck typing

  > Types are defined by the collection of their properties not their name.

  Typescript's implementation of types is as a **structural type system**, which
  contrasts with a nominal type system. This is often referred to colloquially as
  'duck typing': _if it looks like a duck, walks like a duck, and sounds like a
  duck, it probably is a duck_.

  With custom (object types) this means that the following expression of an object
  of type `Age` doesn't generate an error, TS is satisfied that the shapes of each
  match.

  ```tsx
  const martha = {
    name: "Martha",
    yearOfBirth: 1997,
    currentYear: 2021,
    gender: "female",
  };

  const addition: Age = martha;
  ```

  But if we tried to add this extra property whilst defining `martha` as an
  instance of the custom type `Age` , we would get an error:

  ```tsx
  const martha: Age = {
    name: "Martha",
    yearOfBirth: 1997,
    currentYear: 2021,
    gender: "female",
  };
  ```

  ```
  Type '{ name: string; yearOfBirth: number; currentYear: number; ageNow: () => number; gender: string; }' is not assignable to type 'Age'. **Object literal may only specify known properties, and 'gender' does not exist in type 'Age'.**
  ```

  It means that even though in the following, the variable `point` is never
  declared to be of the type `Point` , it matches the shape of the custom type. As
  the structural integrity is maintained, it can be passed to the function without
  error.

  ```tsx
  interface Point {
    x: number;
    y: number;
  }

  function logPoint(p: Point) {
    console.log(`${p.x}, ${p.y}`);
  }

  // logs "12, 26"
  const point = { x: 12, y: 26 };
  logPoint(point);
  ```

  Shape matching only requires a subset of the object's fields to match:

  ```tsx
  const point3 = { x: 12, y: 26, z: 89 };
  logPoint(point3); // logs "12, 26"

  const rect = { x: 33, y: 3, width: 30, height: 80 };
  logPoint(rect);
  ```

  ## Interfaces

  For most purposes the keywords `type` and `interface` are interchangeable in
  TypeScript.

  (The main difference that I have encountered is that Angular specifies that
  interfaces should be used over types, but this is because it is class-based and
  object oriented).

  For me, the main decider is that Angular favours `interface` over `type`. The TS
  handbook recommends using the `type` keyword over `interface`.

  An interface is concept that crosses over from strict OOP and it doesn't quite
  apply to interfaces in TS because an interface is a declaration of a class's
  functions alone, not its data (i.e properties).

raw_content:
  ---
  tags:
    - typescript
  ---

  # Custom types

  Objects and [classes](Classes.md) are where TypeScript becomes most useful and
  powerful. In TypeScript, objects and classes are by definition custom types.

  When typing objects, you do not write the types alongside the actual data as you
  would with primitive types, classes and functions. Instead you write a custom
  type which is a type-annotated object. This is then applied to the object or
  class, where you create instances that **match the shape** of the custom
  declaration.

  So say we have this object:

  ```js
  const age = {
    name: "Thomas",
    yearOfBirth: 1988,
    currentYear: 2021,
    ageNow: function () {
      return this.currentYear - this.yearOfBirth;
    },
  };
  ```

  We could write this as type with the following:

  ```ts
  let Age: {
    name: string;
    yearOfBirth: number;
    currentYear: number;
    ageNow: () => number;
  };
  ```

  (We use `:` because we are declaring a type not intialising a value of the
  type.)

  We could now re-write the first `age` object as an object of type `Age` :

  ```tsx
  let thomas: typeof Age;

  thomas = {
    name: "Thomas",
    yearOfBirth: 1988,
    currentYear: 2021,
    ageNow: function () {
      return this.currentYear - this.yearOfBirth;
    },
  };
  ```

  In practice, defining the type and then asserting that a new variable is of this
  type and then initialising it is rather long-winded. It is better practice to
  simplify the process by creating a **type alias**.

  ```tsx
  type Age = {
    name: string;
    yearOfBirth: number;
    currentYear: number;
    ageNow(): number; // we type the method on the basis of the value it returns
  };
  ```

  We could then create objects based on this:

  ```tsx
  const thomas: Age = {
    name: "Thomas",
    yearOfBirth: 1988,
    currentYear: 2021,
    ageNow: function () {
      return this.currentYear - this.yearOfBirth;
    },
  };
  ```

  Note that we pass in `:Age` as our type declaration, using the custom type in
  the same way as we would use `:string` or `number[]` . We can now use this
  custom type as a type annotation anywhere we use type annotations; it can be
  used exactly the same way as a primitive type in our code.

  `Age` is an alias for the type that `thomas` conforms to.

  The benefit is that TS will correct you if:

  - attempt to assign a type to a value that does not match the custom type
    declaration (for instance: assigning a string value to a property you have
    typed as number)
  - attempt to add a property that is not specified in the custom type declaration

  Although you can subsequently _extend_ the custom type (detailed below).

  ## Duck typing

  > Types are defined by the collection of their properties not their name.

  Typescript's implementation of types is as a **structural type system**, which
  contrasts with a nominal type system. This is often referred to colloquially as
  'duck typing': _if it looks like a duck, walks like a duck, and sounds like a
  duck, it probably is a duck_.

  With custom (object types) this means that the following expression of an object
  of type `Age` doesn't generate an error, TS is satisfied that the shapes of each
  match.

  ```tsx
  const martha = {
    name: "Martha",
    yearOfBirth: 1997,
    currentYear: 2021,
    gender: "female",
  };

  const addition: Age = martha;
  ```

  But if we tried to add this extra property whilst defining `martha` as an
  instance of the custom type `Age` , we would get an error:

  ```tsx
  const martha: Age = {
    name: "Martha",
    yearOfBirth: 1997,
    currentYear: 2021,
    gender: "female",
  };
  ```

  ```
  Type '{ name: string; yearOfBirth: number; currentYear: number; ageNow: () => number; gender: string; }' is not assignable to type 'Age'. **Object literal may only specify known properties, and 'gender' does not exist in type 'Age'.**
  ```

  It means that even though in the following, the variable `point` is never
  declared to be of the type `Point` , it matches the shape of the custom type. As
  the structural integrity is maintained, it can be passed to the function without
  error.

  ```tsx
  interface Point {
    x: number;
    y: number;
  }

  function logPoint(p: Point) {
    console.log(`${p.x}, ${p.y}`);
  }

  // logs "12, 26"
  const point = { x: 12, y: 26 };
  logPoint(point);
  ```

  Shape matching only requires a subset of the object's fields to match:

  ```tsx
  const point3 = { x: 12, y: 26, z: 89 };
  logPoint(point3); // logs "12, 26"

  const rect = { x: 33, y: 3, width: 30, height: 80 };
  logPoint(rect);
  ```

  ## Interfaces

  For most purposes the keywords `type` and `interface` are interchangeable in
  TypeScript.

  (The main difference that I have encountered is that Angular specifies that
  interfaces should be used over types, but this is because it is class-based and
  object oriented).

  For me, the main decider is that Angular favours `interface` over `type`. The TS
  handbook recommends using the `type` keyword over `interface`.

  An interface is concept that crosses over from strict OOP and it doesn't quite
  apply to interfaces in TS because an interface is a declaration of a class's
  functions alone, not its data (i.e properties).


path: zk/Deleting_Mongo_documents.md
sortable_path: zkDeleting_Mongo_documents.md
title: MongoDB: deleting a document from a collection
checksum: d05980b37454803a7e8901255fd6e8fb49cd60535a15ff7927220667bd19b4f6
created: 2024-06-16 17:06:08.674899879+00:00
modified: 2024-06-15 10:00:07.447419012+00:00
metadata: {"tags":["mongo-db","node-js","mongoose","databases"]}
lead:
  ```js
  async function deleteCourse(id) {
    const result = await Course.deleteOne({ id: id });
    console.log(result);
  }
  ```

body:
  ```js
  async function deleteCourse(id) {
    const result = await Course.deleteOne({ id: id });
    console.log(result);
  }
  ```

  Use `findByIdAndRemove([id])` if you want to return the value that is deleted.

  If we were to pass a query object that matches multiple documents in the
  database to `deleteOne` it would only delete the first document returned. To
  delete all use `deleteMany`.

raw_content:
  ---
  tags:
    - mongo-db
    - node-js
    - mongoose
    - databases
  ---

  # MongoDB: deleting a document from a collection

  ```js
  async function deleteCourse(id) {
    const result = await Course.deleteOne({ id: id });
    console.log(result);
  }
  ```

  Use `findByIdAndRemove([id])` if you want to return the value that is deleted.

  If we were to pass a query object that matches multiple documents in the
  database to `deleteOne` it would only delete the first document returned. To
  delete all use `deleteMany`.


path: zk/Forms_in_React.md
sortable_path: zkForms_in_React.md
title: Forms using hooks
checksum: cc03c143d64a475e9141718c7a5ba8853cc79336b8e8bfb2aec36cfac5776c82
created: 2024-06-16 17:06:08.831593401+00:00
modified: 2024-06-15 10:15:53.249753487+00:00
metadata: {"tags":["javascript","react"]}
lead:
  With hooks, form processing is exactly the same as
  [classes](Forms_in_React.md) in terms of the overall
  methodology, but the syntax is slightly different as a result of the `useState`
  hook.

body:
  With hooks, form processing is exactly the same as
  [classes](Forms_in_React.md) in terms of the overall
  methodology, but the syntax is slightly different as a result of the `useState`
  hook.

  >

  ## Basic approach

  Instead of using `this.state` and `this.setState` . We just have the `useState`
  hook. But the controlled component principle is the same. Let's say we have a
  simple email input:

  ```jsx
  const [email, setEmail] = useState("");
  ```

  As this is a form, the state change is going to be the result of user input. So
  we need to prep our form to enable this.

  ```html
  <input type="text" value="{email}" onChange="{setEmail}" />
  ```

  Now we just need to make good on the `setEmail` method we declared when we
  initialised the state:

  ```jsx
  const handleChange = (event) => {
    setEmail(event.target.value);
  };
  ```

  ### Applied example

  Here is an applied example of the above approach for a form that has three input
  fields. This component outputs the inputs as JSON on submit:

  ```jsx

  function FormHook() {
    const [email, setEmail] = useState("");
    const [phone, setPhone] = useState("");
    const [age, setAge] = useState("");
    const [formOutput, setFormOutput] = useState("Form output");

    const handleSubmit = (event) => {
      event.preventDefault();
      setFormOutput(
        JSON.stringify({ email: email, phone: phone, age: age }, null, 2)
      );
    };
  	return (
  		<form onSubmit={handleSubmit}>
  			<input type="text" value={email} onChange={(event) => setEmail(event.target.value)}>
  			<input type="text" value={phone} onChange={(event) => setPhone(event.target.value)}>
  			<input type="number" value={age} onChange={(event) => setAge(event.target.value)}>
  			<button type="submit">Submit</button>
  		</form>
  	)
  };
  ```

  ## More complex forms

  The above is fine if you only have one form with a couple of inputs. But if you
  are managing multiple forms or forms with a complex array of inputs, you would
  need to create `useState` declaration for every single input with a custom
  `onChange` event for each one which is repetitious and not very clean.

  So instead of this, just like with class-based controlled components, we use the
  `name` HTML attribute to distinguish each input and create a generic `onChange`
  function that distinguishes each separate input by destructuring a key, value
  object using the `name`.

  ```jsx
  <form onSubmit={handleSubmit}>
  			<input type="text" name="email" value={formValues.email} onChange={handleChange}>
  			<input type="text" name="phone" value={formValues.phone} onChange={handleChange}>
  			<input type="number" name="age" value={formValues.age} onChange={handleChange}>
  			<button type="submit">Submit</button>
  </form>
  ```

  ```jsx
  const initialState = {
    email: "",
    phone: "",
    age: "",
  };

  const [formValues, setFormValues] = useState(initialState);

  const handleChange = (event) => {
    const { name, value } = event.target;
    setFormValues({ ...formValues, [name]: value });
  };
  ```

  There are three parts:

  1. First we create the initial state.
  2. Next we store this initial state as the variable in the `useState`
     initialisation: `formValues` . We also provide a method `setFormValues` which
     will be used by the change handler to log the user's inputs.
  3. Finally we create the function that will log the user changes. First we use
     object destructuring on the change event to enable us to retrieve the `name`
     and `value` attributes of the HTML inputs in the component. Then we use
     spread syntax to say that for each input pair, retrieve its value, using the
     destructured `name` variable as the key.

  ### Applied example

  Below I have updated the previous context to this time reflect the new,
  abstracted logic:

  ```jsx
  function FormHookAbstracted() {
    const initialState = {
      email: "",
      phone: "",
      age: "",
    };
  	const [formValues, setFormValues] = useState(initialState);
  	const handleChange = (event) => {
      const { name, value } = event.target;
      setFormValues({ ...formValues, [name]: value });
    };
    const handleSubmit = (event) => {
      event.preventDefault();
      setFormOutput(
        JSON.stringify({ email: email, phone: phone, age: age }, null, 2)
      );
    };
  	return (
  		<form onSubmit={handleSubmit}>
  			<input type="text" name="email" value={formValues.email} onChange={handleChange}>
  			<input type="text" name="phone" value={formValues.phone} onChange={handleChange}>
  			<input type="number" name="age" value={formValues.age} onChange={handleChange}>
  			<button type="submit">Submit</button>
  		</form>
  	)
  };
  export default FormHookAbstracted;
  ```

  Note that instead of individual variables `email` , `phone`, `age` , this
  approach returns a single object `formValues` . We could therefore access the
  individual values with e.g `[formValues.email](formvalues.email)` .

  As it is an object, it makes resetting to the original state very easy, viz:

  ```jsx
  const handleReset = () => {
    Object.values(formValues).map((x) => setFormValues(initialState));
  };
  ```

raw_content:
  ---
  tags:
    - javascript
    - react
  ---

  # Forms using hooks

  With hooks, form processing is exactly the same as
  [classes](Forms_in_React.md) in terms of the overall
  methodology, but the syntax is slightly different as a result of the `useState`
  hook.

  >

  ## Basic approach

  Instead of using `this.state` and `this.setState` . We just have the `useState`
  hook. But the controlled component principle is the same. Let's say we have a
  simple email input:

  ```jsx
  const [email, setEmail] = useState("");
  ```

  As this is a form, the state change is going to be the result of user input. So
  we need to prep our form to enable this.

  ```html
  <input type="text" value="{email}" onChange="{setEmail}" />
  ```

  Now we just need to make good on the `setEmail` method we declared when we
  initialised the state:

  ```jsx
  const handleChange = (event) => {
    setEmail(event.target.value);
  };
  ```

  ### Applied example

  Here is an applied example of the above approach for a form that has three input
  fields. This component outputs the inputs as JSON on submit:

  ```jsx

  function FormHook() {
    const [email, setEmail] = useState("");
    const [phone, setPhone] = useState("");
    const [age, setAge] = useState("");
    const [formOutput, setFormOutput] = useState("Form output");

    const handleSubmit = (event) => {
      event.preventDefault();
      setFormOutput(
        JSON.stringify({ email: email, phone: phone, age: age }, null, 2)
      );
    };
  	return (
  		<form onSubmit={handleSubmit}>
  			<input type="text" value={email} onChange={(event) => setEmail(event.target.value)}>
  			<input type="text" value={phone} onChange={(event) => setPhone(event.target.value)}>
  			<input type="number" value={age} onChange={(event) => setAge(event.target.value)}>
  			<button type="submit">Submit</button>
  		</form>
  	)
  };
  ```

  ## More complex forms

  The above is fine if you only have one form with a couple of inputs. But if you
  are managing multiple forms or forms with a complex array of inputs, you would
  need to create `useState` declaration for every single input with a custom
  `onChange` event for each one which is repetitious and not very clean.

  So instead of this, just like with class-based controlled components, we use the
  `name` HTML attribute to distinguish each input and create a generic `onChange`
  function that distinguishes each separate input by destructuring a key, value
  object using the `name`.

  ```jsx
  <form onSubmit={handleSubmit}>
  			<input type="text" name="email" value={formValues.email} onChange={handleChange}>
  			<input type="text" name="phone" value={formValues.phone} onChange={handleChange}>
  			<input type="number" name="age" value={formValues.age} onChange={handleChange}>
  			<button type="submit">Submit</button>
  </form>
  ```

  ```jsx
  const initialState = {
    email: "",
    phone: "",
    age: "",
  };

  const [formValues, setFormValues] = useState(initialState);

  const handleChange = (event) => {
    const { name, value } = event.target;
    setFormValues({ ...formValues, [name]: value });
  };
  ```

  There are three parts:

  1. First we create the initial state.
  2. Next we store this initial state as the variable in the `useState`
     initialisation: `formValues` . We also provide a method `setFormValues` which
     will be used by the change handler to log the user's inputs.
  3. Finally we create the function that will log the user changes. First we use
     object destructuring on the change event to enable us to retrieve the `name`
     and `value` attributes of the HTML inputs in the component. Then we use
     spread syntax to say that for each input pair, retrieve its value, using the
     destructured `name` variable as the key.

  ### Applied example

  Below I have updated the previous context to this time reflect the new,
  abstracted logic:

  ```jsx
  function FormHookAbstracted() {
    const initialState = {
      email: "",
      phone: "",
      age: "",
    };
  	const [formValues, setFormValues] = useState(initialState);
  	const handleChange = (event) => {
      const { name, value } = event.target;
      setFormValues({ ...formValues, [name]: value });
    };
    const handleSubmit = (event) => {
      event.preventDefault();
      setFormOutput(
        JSON.stringify({ email: email, phone: phone, age: age }, null, 2)
      );
    };
  	return (
  		<form onSubmit={handleSubmit}>
  			<input type="text" name="email" value={formValues.email} onChange={handleChange}>
  			<input type="text" name="phone" value={formValues.phone} onChange={handleChange}>
  			<input type="number" name="age" value={formValues.age} onChange={handleChange}>
  			<button type="submit">Submit</button>
  		</form>
  	)
  };
  export default FormHookAbstracted;
  ```

  Note that instead of individual variables `email` , `phone`, `age` , this
  approach returns a single object `formValues` . We could therefore access the
  individual values with e.g `[formValues.email](formvalues.email)` .

  As it is an object, it makes resetting to the original state very easy, viz:

  ```jsx
  const handleReset = () => {
    Object.values(formValues).map((x) => setFormValues(initialState));
  };
  ```


path: zk/Importing_MongoDB_data.md
sortable_path: zkImporting_MongoDB_data.md
title: Importing data to MongoDB
checksum: 677b579e14fd2d752e80d93d1b76f3f2d113a7454f3689917dc8a11c9b4564cd
created: 2024-06-16 17:06:08.843775026+00:00
modified: 2024-06-15 10:03:04.113949676+00:00
metadata: {"tags":["mongo-db","node-js","databases"]}
lead:
  We can use the command line to import data into a Mongo database. We can also
  combine the importing of data with the creation of a database:

body:
  We can use the command line to import data into a Mongo database. We can also
  combine the importing of data with the creation of a database:

  ```bash
  mongoimport --db [preexisting_or_new_database name] --collection [collection_name] --file sourcedata.json --jsonArray
  ```

  We use `--jsonArray` to indicate the format of the data we are importing.

  Once this has executed, the data will be visible in Compass.

raw_content:
  ---
  tags:
    - mongo-db
    - node-js
    - databases
  ---

  # Importing data to MongoDB

  We can use the command line to import data into a Mongo database. We can also
  combine the importing of data with the creation of a database:

  ```bash
  mongoimport --db [preexisting_or_new_database name] --collection [collection_name] --file sourcedata.json --jsonArray
  ```

  We use `--jsonArray` to indicate the format of the data we are importing.

  Once this has executed, the data will be visible in Compass.


path: zk/Iterating_in_React.md
sortable_path: zkIterating_in_React.md
title: Iterating through data
checksum: a417bdd27a8eaa5408dcb27982df7ef2466161fa88eeacb315e39b99b39ad4d2
created: 2024-06-16 17:06:08.849817632+00:00
modified: 2024-06-15 10:16:02.066608067+00:00
metadata: {"tags":["javascript","react"]}
lead:
  As React follows the **functional programming paradigm** and state versioning,
  looping is not the recommended way of engineering repeated processes since it
  presupposes pre-existing state. Instead React relies on the functional methods
  of modern JavaScript such as `map` , `filter` , `reduce` to output the values of
  iterative data structures.

body:
  As React follows the **functional programming paradigm** and state versioning,
  looping is not the recommended way of engineering repeated processes since it
  presupposes pre-existing state. Instead React relies on the functional methods
  of modern JavaScript such as `map` , `filter` , `reduce` to output the values of
  iterative data structures.

  Instead of mutating the state of a reference type, these methods are
  'non-destructive': they create a new array that meets the requirements set in
  the particular method. These newly created arrays and objects therefore form the
  basis of the state versioning, because each new array that is engendered, is a
  new state configuration.

  ## The `key` attribute

  The `key` attribute is a special React attribute that should be added to the
  elements of any listed content (i.e numbered lists, unordered lists, `select`
  options etc; basically anything rendered that comes about through mapping arrays
  and objects).

  This enables React to monitor the state of the list: which items have changed,
  been added, or removed.

  The best way to pick a key is to use a string that uniquely identifies a list
  item among its siblings.

  For instance, using our earlier `numbers` array, assuming each number is unique,
  we could use the number itself as the key:

  ```jsx
  const numbers = [1, 2, 3, 4, 5];
  const listItems = numbers.map((number) => (
    <li key={number.toString()}> {number}</li>
  ));
  ```

  > Keys have to be unique to the individual element and not shared by any other
  > sibling. But they do not need to be globally unique. You could use the same
  > `key` name in another array list.

  > Keys should be string types, not other data types. You can use the
  > `.toString()` method to ensure this is the case.

  If you can't find a unique basis for naming a series of keys, you can use the
  `index` value of the `Array.map` function. This should only be used if the order
  of the items doesn't change. An example:

  ```jsx
  class List extends React.Component {
    render() {
      const demoArr = ["cat", "dog", "mouse"];
      return (
          <ul>
            {demoArr.map((x, index) => (
              <li key={index}>{x}</li>
            ))}
          </ul>
        </div>
      );
    }
  }
  ```

  ## Demonstration

  ### Source data

  ```jsx
  const blogData = [
    {
      id: 1,
      date: "2020-11-15",
          shortByline:
        "Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. ",
      longByline:
        "Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor.",
      image: blogImage,
    },
    {
      id: 2,
      date: "2020-08-11",
          shortByline:
        "Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. ",
      longByline:
        "Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor.",
      image: blogImage,
    },
  ];
  ```

  ### Child component

  ```jsx
  export default function BlogPreviewCard(props) {
    return (
      <Card>
        <CardMedia image={props.image} />
        <CardContent>
          <Typography>{props.date}</Typography>
          <Typography>{props.title}</Typography>
          <Typography>{props.shortByline}</Typography>
        </CardContent>
        <CardActions>
          <Button>Read</Button>
        </CardActions>
      </Card>
    );
  }
  ```

  ### Iteration

  ```jsx
  // This uses the Material-UI grid component

  import BlogPreviewCard from "../components/BlogPreviewCard"
  import blogData from "../data/blogData

  export default function BlogPreviewSet() {
    return (
      <Grid>
        {blogDummyData.map((data, index) => (
          <Grid key={index}>
            <BlogPreviewCard key={index} {...data} />
          </Grid>
        ))}
      </Grid>
    )
  }
  ```

raw_content:
  ---
  tags:
    - javascript
    - react
  ---

  # Iterating through data

  As React follows the **functional programming paradigm** and state versioning,
  looping is not the recommended way of engineering repeated processes since it
  presupposes pre-existing state. Instead React relies on the functional methods
  of modern JavaScript such as `map` , `filter` , `reduce` to output the values of
  iterative data structures.

  Instead of mutating the state of a reference type, these methods are
  'non-destructive': they create a new array that meets the requirements set in
  the particular method. These newly created arrays and objects therefore form the
  basis of the state versioning, because each new array that is engendered, is a
  new state configuration.

  ## The `key` attribute

  The `key` attribute is a special React attribute that should be added to the
  elements of any listed content (i.e numbered lists, unordered lists, `select`
  options etc; basically anything rendered that comes about through mapping arrays
  and objects).

  This enables React to monitor the state of the list: which items have changed,
  been added, or removed.

  The best way to pick a key is to use a string that uniquely identifies a list
  item among its siblings.

  For instance, using our earlier `numbers` array, assuming each number is unique,
  we could use the number itself as the key:

  ```jsx
  const numbers = [1, 2, 3, 4, 5];
  const listItems = numbers.map((number) => (
    <li key={number.toString()}> {number}</li>
  ));
  ```

  > Keys have to be unique to the individual element and not shared by any other
  > sibling. But they do not need to be globally unique. You could use the same
  > `key` name in another array list.

  > Keys should be string types, not other data types. You can use the
  > `.toString()` method to ensure this is the case.

  If you can't find a unique basis for naming a series of keys, you can use the
  `index` value of the `Array.map` function. This should only be used if the order
  of the items doesn't change. An example:

  ```jsx
  class List extends React.Component {
    render() {
      const demoArr = ["cat", "dog", "mouse"];
      return (
          <ul>
            {demoArr.map((x, index) => (
              <li key={index}>{x}</li>
            ))}
          </ul>
        </div>
      );
    }
  }
  ```

  ## Demonstration

  ### Source data

  ```jsx
  const blogData = [
    {
      id: 1,
      date: "2020-11-15",
          shortByline:
        "Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. ",
      longByline:
        "Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor.",
      image: blogImage,
    },
    {
      id: 2,
      date: "2020-08-11",
          shortByline:
        "Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. ",
      longByline:
        "Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor.",
      image: blogImage,
    },
  ];
  ```

  ### Child component

  ```jsx
  export default function BlogPreviewCard(props) {
    return (
      <Card>
        <CardMedia image={props.image} />
        <CardContent>
          <Typography>{props.date}</Typography>
          <Typography>{props.title}</Typography>
          <Typography>{props.shortByline}</Typography>
        </CardContent>
        <CardActions>
          <Button>Read</Button>
        </CardActions>
      </Card>
    );
  }
  ```

  ### Iteration

  ```jsx
  // This uses the Material-UI grid component

  import BlogPreviewCard from "../components/BlogPreviewCard"
  import blogData from "../data/blogData

  export default function BlogPreviewSet() {
    return (
      <Grid>
        {blogDummyData.map((data, index) => (
          <Grid key={index}>
            <BlogPreviewCard key={index} {...data} />
          </Grid>
        ))}
      </Grid>
    )
  }
  ```


path: zk/Memoization_in_React.md
sortable_path: zkMemoization_in_React.md
title: Memoization with useCallback and useMemo
lead: ## Rationale
checksum: aa5a1396de6830c65cebe440419eb402597ac57d198d06fa5c5fe6cea81ab4f9
created: 2024-06-16 17:06:08.981303866+00:00
modified: 2024-06-15 10:16:35.867324488+00:00
metadata: {"tags":["javascript","react"]}
body:
  ## Rationale

  In the lifecycle of a component, React re-renders the component when an update
  is made. When React checks for any changes in a component, it may detect an
  unintended or unexpected change due to how JavaScript handles equality and
  shallow comparisons. This change in the React application will cause it to
  re-render unnecessarily.

  Additionally, if that re-rendering is an expensive operation, like a long for
  loop, it can hurt performance. Expensive operations can be costly in either
  time, memory, or processing. In addition to potential technical issues, this may
  lead to poor user experience.

  If one part re-renders, it re-renders the entire component tree. `useCallback`
  and `useMemo` can be used reduce this performance impact.

  ## useCallback

  The `useCallback` hook is used to wrap functions. It tells React to not
  re-create a wrapped function when a component re-renders, unless any of the
  useCallback's dependencies change.

  `useCallback` returns a memoized version of the callback function it is passed.
  This means that the function object returned from useCallback will be the same
  between re-renders.

  Remember that in JavaScript, functions are objects and components are functions.
  As a result, every time a component containing a function re-renders, it create
  a new instance of the function in memory.

  > Given the same dependency value, the `useCallback` hook returns the same
  > function instance between renderings (aka memoization).

  This said, for small functions that are not intensive, it doesn't really matter
  if they are not memoized.

  ### Syntax

  A standard case of this would be a function that runs on a button click, for
  instance when sending data from a form to a server. In the example below there
  is quite a lot going on, and most of it is independent of the actual UI-cycle of
  the component.

  ```jsx
  const handleSubmit = useCallback(
    async (formValues) => {
      setPendSaveConfig(true);
      const payload = new GenerateConfig({
        workflowId: project_id,
        blockId: blockId,
        config: formValues,
      });
      axios
        .post(`${process.env.REACT_APP_ENDPOINT}/save-block-config`, payload)
        .then((res) => console.log(res))
        .finally(() => setPendSaveConfig(false))
        .catch((err) => console.error(err));
    },
    [blockId, project_id]
  );
  ```

  Note that the syntax is similar to [React_useEffect](React_useEffect.md): there is a
  dependency array. The effect is the same: the function contained within
  `useCallback` will only re-rendered if one of these dependencies changes.
  However (see next section) the function will run in its memoized form on every
  click.

  ### Reference versus result

  `useCallback` only memoizes the function _object_ (the reference) not the value
  that is _returned_ by the function (the result).

  In the example below, the `calculatePi()` function reference will not change
  between renders but each time the click event fires, the value returned by
  `calculatePi()` will change. In other words, it will be assigned fresh memory.

  ```jsx
  function ParentComponent() {
    const onHandleClick = useCallback(() => {
      const special = calculatePi();
    });

    return <SubComponent handleClick={onHandleClick} />;
  }
  ```

  ### Use cases

  You should not apply `useCallback` in a blanket fashion, this can reduce
  performance rather than improve it. The best scenarios are:

  1. A functional component wrapped inside React.memo() accepts a function object
     prop

  2. When the function object is a dependency to other hooks, e.g.
     `useEffect(..., [callback])`

  3. When the function has some internal state, e.g. when the function is
     debounced or throttled.

  ## useMemo

  We can think of `useMemo` as a complement to `useCallback`. The main difference
  is that whilst `useCallback` memoizes the function reference, `useMemo` memoizes
  the function result; the value that is returned.

  > In memoization, the result is “remembered” when the same parameters are
  > passed-in subsequently. If we have a function compute 1 + 1, it will return 2.
  > But if it uses memoization, the next time we run 1’s through the function, it
  > won’t add them up; it will just remember the answer is 2 without executing the
  > adding function.

  Like `useCallback`, `useMemo` takes a function and an array of dependencies for
  the same reason: if one of the dependencies changes then the function will
  recalculate (and re-memoize) the result but they don't the same memoized value
  will be returned.

  As with `useCallback`, `useMemo` is best applied to complex functions that are
  computationally expensive, it shouldn't be used indiscriminately.

  It should not be used with asynchronous functions, in these instances,
  `useEffect` would be a better choice.

  ### Syntax

  ```jsx
  const List = React.useMemo(
    () =>
      listOfItems.map((item) => ({
        ...item,
        itemProp1: expensiveFunction(props.first),
        itemProp2: anotherPriceyFunction(props.second),
      })),
    [listOfItems]
  );
  ```

raw_content:
  ---
  tags:
    - javascript
    - react
  ---

  # Memoization with useCallback and useMemo

  ## Rationale

  In the lifecycle of a component, React re-renders the component when an update
  is made. When React checks for any changes in a component, it may detect an
  unintended or unexpected change due to how JavaScript handles equality and
  shallow comparisons. This change in the React application will cause it to
  re-render unnecessarily.

  Additionally, if that re-rendering is an expensive operation, like a long for
  loop, it can hurt performance. Expensive operations can be costly in either
  time, memory, or processing. In addition to potential technical issues, this may
  lead to poor user experience.

  If one part re-renders, it re-renders the entire component tree. `useCallback`
  and `useMemo` can be used reduce this performance impact.

  ## useCallback

  The `useCallback` hook is used to wrap functions. It tells React to not
  re-create a wrapped function when a component re-renders, unless any of the
  useCallback's dependencies change.

  `useCallback` returns a memoized version of the callback function it is passed.
  This means that the function object returned from useCallback will be the same
  between re-renders.

  Remember that in JavaScript, functions are objects and components are functions.
  As a result, every time a component containing a function re-renders, it create
  a new instance of the function in memory.

  > Given the same dependency value, the `useCallback` hook returns the same
  > function instance between renderings (aka memoization).

  This said, for small functions that are not intensive, it doesn't really matter
  if they are not memoized.

  ### Syntax

  A standard case of this would be a function that runs on a button click, for
  instance when sending data from a form to a server. In the example below there
  is quite a lot going on, and most of it is independent of the actual UI-cycle of
  the component.

  ```jsx
  const handleSubmit = useCallback(
    async (formValues) => {
      setPendSaveConfig(true);
      const payload = new GenerateConfig({
        workflowId: project_id,
        blockId: blockId,
        config: formValues,
      });
      axios
        .post(`${process.env.REACT_APP_ENDPOINT}/save-block-config`, payload)
        .then((res) => console.log(res))
        .finally(() => setPendSaveConfig(false))
        .catch((err) => console.error(err));
    },
    [blockId, project_id]
  );
  ```

  Note that the syntax is similar to [React_useEffect](React_useEffect.md): there is a
  dependency array. The effect is the same: the function contained within
  `useCallback` will only re-rendered if one of these dependencies changes.
  However (see next section) the function will run in its memoized form on every
  click.

  ### Reference versus result

  `useCallback` only memoizes the function _object_ (the reference) not the value
  that is _returned_ by the function (the result).

  In the example below, the `calculatePi()` function reference will not change
  between renders but each time the click event fires, the value returned by
  `calculatePi()` will change. In other words, it will be assigned fresh memory.

  ```jsx
  function ParentComponent() {
    const onHandleClick = useCallback(() => {
      const special = calculatePi();
    });

    return <SubComponent handleClick={onHandleClick} />;
  }
  ```

  ### Use cases

  You should not apply `useCallback` in a blanket fashion, this can reduce
  performance rather than improve it. The best scenarios are:

  1. A functional component wrapped inside React.memo() accepts a function object
     prop

  2. When the function object is a dependency to other hooks, e.g.
     `useEffect(..., [callback])`

  3. When the function has some internal state, e.g. when the function is
     debounced or throttled.

  ## useMemo

  We can think of `useMemo` as a complement to `useCallback`. The main difference
  is that whilst `useCallback` memoizes the function reference, `useMemo` memoizes
  the function result; the value that is returned.

  > In memoization, the result is “remembered” when the same parameters are
  > passed-in subsequently. If we have a function compute 1 + 1, it will return 2.
  > But if it uses memoization, the next time we run 1’s through the function, it
  > won’t add them up; it will just remember the answer is 2 without executing the
  > adding function.

  Like `useCallback`, `useMemo` takes a function and an array of dependencies for
  the same reason: if one of the dependencies changes then the function will
  recalculate (and re-memoize) the result but they don't the same memoized value
  will be returned.

  As with `useCallback`, `useMemo` is best applied to complex functions that are
  computationally expensive, it shouldn't be used indiscriminately.

  It should not be used with asynchronous functions, in these instances,
  `useEffect` would be a better choice.

  ### Syntax

  ```jsx
  const List = React.useMemo(
    () =>
      listOfItems.map((item) => ({
        ...item,
        itemProp1: expensiveFunction(props.first),
        itemProp2: anotherPriceyFunction(props.second),
      })),
    [listOfItems]
  );
  ```


path: zk/Modelling_relationships_in_MongoDB.md
sortable_path: zkModelling_relationships_in_MongoDB.md
title: Modelling relationships between data
checksum: c7525be2f33aacca299e720d1ac1ad731bffae9e7b52c6557609fb4a43532a0e
created: 2024-06-16 17:06:09.054377213+00:00
modified: 2024-06-15 10:03:44.821349335+00:00
metadata: {"tags":["mongo-db","node-js","mongoose","databases"]}
lead:
  So far we have taken the values of a document to be simple: the `author` value
  is just a string but what if `author` was itself another collection for instance
  a collection with the proprties `age` and `publications` and the author name,
  say `Tosh Gnomay` was a document in this collection? This means we would have an
  interaction between two collections. In this entry we will look at how to work
  with interrelated collections. This is equivalent to establishing
  [joins](10_Joins.md) in a relational database.

body:
  So far we have taken the values of a document to be simple: the `author` value
  is just a string but what if `author` was itself another collection for instance
  a collection with the proprties `age` and `publications` and the author name,
  say `Tosh Gnomay` was a document in this collection? This means we would have an
  interaction between two collections. In this entry we will look at how to work
  with interrelated collections. This is equivalent to establishing
  [joins](10_Joins.md) in a relational database.

  There are two main approaches to modelling relationships between data:
  **normalisation** and **denormalisation**.

  ## Modelling relationships with normalisation: using references

  In the case of normalisation we use a UUID from one document to connect it to
  another document.

  Let's say that we have a course document as follows which is an instance of the
  `courses` collection:

  ```js
  {
      _id: "ceds89e"
      name: "Java course",
      author: "Tosh Gnomay"
  }
  ```

  And we have a document which is an instance of another type of collection called
  `authors`. One instance of it could be:

  ```js
  {
      _id: "de89w9",
      name: "Tosh Gnomay",
      courses: ["Java course", "C# course"]
  }
  ```

  Using normalisation, we would establish the relationship by using the value of
  the `_id` propety in the `courses` document as the value of the `name` property
  in the `authors` document. We would rewrite the `courses` document like so:

  ```js
  {
      _id: "ceds89e"
      name: "Java course",
      author: "de89w9"
  }
  ```

  ## Modelling relationships with denormalisation: embedding

  With denormalisation we achieve the same outcome but instead of using a
  reference we embed one value in another:

  ```js
  {
      _id: "ceds89e"
      name: "Java course",
      author: {
          name: "Tosh Gnomay",
          courses: ["Java course", "C# course"]
      }
  }
  ```

  ## Tradeoffs: which approach to use?

  There are drawbacks and benefits with each approach.

  - One benefit of normalisation is consistency. Because we are using the UUID and
    referencing it in another document, if we make a change to the values in the
    source document, it will automatically apply to all documents that reference
    it. We make a change in one place and it is reflected everywhere.

  - Conversely, a drawback of denormalisation is that it invites inconsistency
    between documents. Embedded values can easily go out of sync with their usage
    elsewhere as you don't have a direct reference correspondence.

  - On the other hand a drawback of normalisation is performance when querying.
    Any time you have a document that references another document than this
    document also has to be retrieved. Therefore for every query you are returning
    two documents. As denormalised references embed the second document, only one
    document is being returned on each query.

raw_content:
  ---
  tags:
    - mongo-db
    - node-js
    - mongoose
    - databases
  ---

  # Modelling relationships between data

  So far we have taken the values of a document to be simple: the `author` value
  is just a string but what if `author` was itself another collection for instance
  a collection with the proprties `age` and `publications` and the author name,
  say `Tosh Gnomay` was a document in this collection? This means we would have an
  interaction between two collections. In this entry we will look at how to work
  with interrelated collections. This is equivalent to establishing
  [joins](10_Joins.md) in a relational database.

  There are two main approaches to modelling relationships between data:
  **normalisation** and **denormalisation**.

  ## Modelling relationships with normalisation: using references

  In the case of normalisation we use a UUID from one document to connect it to
  another document.

  Let's say that we have a course document as follows which is an instance of the
  `courses` collection:

  ```js
  {
      _id: "ceds89e"
      name: "Java course",
      author: "Tosh Gnomay"
  }
  ```

  And we have a document which is an instance of another type of collection called
  `authors`. One instance of it could be:

  ```js
  {
      _id: "de89w9",
      name: "Tosh Gnomay",
      courses: ["Java course", "C# course"]
  }
  ```

  Using normalisation, we would establish the relationship by using the value of
  the `_id` propety in the `courses` document as the value of the `name` property
  in the `authors` document. We would rewrite the `courses` document like so:

  ```js
  {
      _id: "ceds89e"
      name: "Java course",
      author: "de89w9"
  }
  ```

  ## Modelling relationships with denormalisation: embedding

  With denormalisation we achieve the same outcome but instead of using a
  reference we embed one value in another:

  ```js
  {
      _id: "ceds89e"
      name: "Java course",
      author: {
          name: "Tosh Gnomay",
          courses: ["Java course", "C# course"]
      }
  }
  ```

  ## Tradeoffs: which approach to use?

  There are drawbacks and benefits with each approach.

  - One benefit of normalisation is consistency. Because we are using the UUID and
    referencing it in another document, if we make a change to the values in the
    source document, it will automatically apply to all documents that reference
    it. We make a change in one place and it is reflected everywhere.

  - Conversely, a drawback of denormalisation is that it invites inconsistency
    between documents. Embedded values can easily go out of sync with their usage
    elsewhere as you don't have a direct reference correspondence.

  - On the other hand a drawback of normalisation is performance when querying.
    Any time you have a document that references another document than this
    document also has to be retrieved. Therefore for every query you are returning
    two documents. As denormalised references embed the second document, only one
    document is being returned on each query.


path: zk/MongoDB_Introduction.md
sortable_path: zkMongoDB_Introduction.md
title: MongoDB: Introduction
checksum: 13cf7e8e089a48db143051dddb2c02e86449cf2858d7aa9e44ec492618a668f5
created: 2024-06-16 17:06:09.070860404+00:00
modified: 2024-06-15 10:03:10.864071307+00:00
metadata: {"tags":["mongo-db","databases"]}
lead:
  MongoDB is not a relational database system like SQL, instead it is
  document-based which means you do not neeed to design database tables and
  schema, you are simply storing data as JSON and there is no transformation of
  the data.

body:
  MongoDB is not a relational database system like SQL, instead it is
  document-based which means you do not neeed to design database tables and
  schema, you are simply storing data as JSON and there is no transformation of
  the data.

  Most of the notes on Mongo will introduce it within the context of Node.js
  backend. We will be sending Javascript objects and arrays to Mongo and returning
  them as JSON.

  ## Databases, collections, documents

  Although Mongo is not a relational database it has a structure that we can
  understand in relation to that paradigm. A **database** is obviously the overall
  structure. It comprises **collections** which are organised sets of data that
  are analagous to [tables](Relational_database_architecture.md#table)
  in RDBs. Within each collection are a series of **documents** which we can think
  of as being equivalent to [rows](Relational_database_architecture.md)
  in RDB table: units that comprise the collection.

  A document is a container comprising key-value pairs in the manner of an object.

  ![](/img/mongo-db-structure.svg)

raw_content:
  ---
  tags:
    - mongo-db
    - databases
  ---

  # MongoDB: Introduction

  MongoDB is not a relational database system like SQL, instead it is
  document-based which means you do not neeed to design database tables and
  schema, you are simply storing data as JSON and there is no transformation of
  the data.

  Most of the notes on Mongo will introduce it within the context of Node.js
  backend. We will be sending Javascript objects and arrays to Mongo and returning
  them as JSON.

  ## Databases, collections, documents

  Although Mongo is not a relational database it has a structure that we can
  understand in relation to that paradigm. A **database** is obviously the overall
  structure. It comprises **collections** which are organised sets of data that
  are analagous to [tables](Relational_database_architecture.md#table)
  in RDBs. Within each collection are a series of **documents** which we can think
  of as being equivalent to [rows](Relational_database_architecture.md)
  in RDB table: units that comprise the collection.

  A document is a container comprising key-value pairs in the manner of an object.

  ![](/img/mongo-db-structure.svg)


path: zk/Querying_a_Mongo_collection.md
sortable_path: zkQuerying_a_Mongo_collection.md
title: Query a Mongo collection with Mongoose
lead: We now have the following entries in our `courses` collection:
checksum: f4ac5106a9a718493ccba4d322bf1aff6ee105a11d648db5e50ffee8b902e7d7
created: 2024-06-16 17:06:09.223175479+00:00
modified: 2024-06-15 10:04:13.698535251+00:00
metadata: {"tags":["mongo-db","node-js","mongoose","databases"]}
body:
  We now have the following entries in our `courses` collection:

  ```js
  {
    name: 'Python Course',
    author: 'Terry Ogleton',
    tags: [ 'python', 'backend' ],
    isPublished: true,
    _id: new ObjectId("62f4e2527ac4aa2c30d41d23"),
    date: 2022-08-11T11:04:50.750Z,
    __v: 0
  }

  {
    name: 'Javascript Course',
    author: 'Tosh Gnomay',
    tags: [ 'js', 'frontend' ],
    isPublished: true,
    _id: new ObjectId("62f4e2527ac4aa2c30d41d24"),
    date: 2022-08-11T11:04:50.750Z,
    __v: 0
  }

  ```

  Now we will query the collection. This capability is provided via the Mongoose
  schema class we used to create the `Course`
  [model](Create_collections_and_documents_with_Mongoose.md#models).
  We have the following methods available to use from the schema:

  - `find`
  - `findById`
  - `findByIdAndRemove`
  - `findByIdAndUpdate`
  - `findOne`
  - `findOneAndUpdate`
  - `findOneAndRemove`
  - ...

  The various `find` methods return a value that is promisified.

  ## Return values with `find`

  ```js
  async function getCourses() {
    const courses = await Course.find();
    console.log(courses);
  }
  ```

  ## Filter values returned

  This will return all the published courses where Tosh Gnomay is the author:

  ```js
  async function getCourses() {
    const courses = await Course.find({
      author: "Tosh Gnomay",
      isPublished: true,
    });
    console.log(courses);
  }
  ```

  This time we will filter by the same author but we will add additional
  parameters to distinguish:

  - only the first ten entries (using `.limit(10)`)
  - sort ascending by name (using `.sort({name: 1}))` , to descend we would use
    `-1`)
  - only return the properties `name` and `tags` for the item in the collection
    (using `.select({name: 1, tags: 1})`)

  ```js
  async function getCourses() {
    const courses = await Course.find({
      author: "Tosh Gnomay",
      isPublished: true,
    })
      .limit(10)
      .sort({ name: 1 })
      .select({ name: 1, tags: 1 });
    console.log(courses);
  }
  ```

  This returns:

  ```js
  [
    {
      _id: new ObjectId("62f4f07a875cff48827b8731"),
      name: "Java Course",
      tags: ["java", "backend"],
    },
    {
      _id: new ObjectId("62f4e2527ac4aa2c30d41d24"),
      name: "Javascript Course",
      tags: ["js", "frontend"],
    },
  ];
  ```

  > Note that the UUID is always returned, whether we specify it or not.

  ## Querying with operators

  So far when filtering we have been doing so with reference to properties that
  exist on the document's model (`author`, `isPublished` etc) and we have applied
  tranformations on the data returned (sorting, limiting the number or matches
  etc.). However we can also apply **operators** within our queries. Operators
  allow us to perform computations on the data, for example: for a given numerical
  property on an object, return the objects for which this value is within a
  certain range.

  When we apply operators we use the `$` symbol before the operator and pass the
  operator function as an object.

  The schema:

  ```
  Model.find( { property: { $operator: conditions } } )
  ```

  ### Comparison operators

  The following comparison operators are available in MongoDB:

  | Operator | Function                  |
  | -------- | ------------------------- |
  | `eq`     | Equal to                  |
  | `ne`     | Not equal to              |
  | `gt`     | Greater than              |
  | `gte`    | Greater than or less than |
  | `lt`     | Less than                 |
  | `lte`    | Less than or equal to     |
  | `in`     | In                        |
  | `nin`    | Not in                    |

  We can employ these comparators within a `.find` filter. For example let's
  imagine that our `courses` instances have a property of `price`.

  To filter course prices that are greater than or equal to 10 and less than or
  equal to 29:

  ```js
  Course.find({ price: { $gte: 10, $lte: 20 } });
  ```

  To filter course prices that are either 10, 15 or 20:

  ```js
  Course.find({ price: { $in: [10, 15, 20] } });
  ```

  ### Logical operators

  When we apply logical operators, we do not apply the query within the main
  `find` method. We use a dedicated method that corresponds to the logical
  predicate.

  For example to query by logical
  [OR](Truth-functional_connectives.md#disjunction):

  ```js
  async function getCourses() {
    const courses = await Course.find().or([
      { author: "Tosh Gnomay" },
      { isPublished: true },
    ]);
    console.log(courses);
  }
  ```

  We write each disjunct as an object representing the conditions we are filtering
  for within an array that is passed to the `.or()` method.

  The same syntax applies for conjunction.

  ### Regular expressions

  When filtering by strings we can use Regex for greater power.

  Previously we filtered by the author name:

  ```js
  .find({author: "Tosh Gnomay"})
  ```

  To demonstrate regex we could filter by names beginning with `T`:

  ```js
  .find({author: /^T*/})
  ```

  ```js
  async function getCourses() {
    const courses = await Course.find()
      .or([{ author: "Tosh Gnomay" }, { isPublished: true }])
      .count();
    console.log(courses);
  }
  ```

  This will return a number.

  ### Pagination

  We previously used the `limit()` method to control how many matches we return
  from a query. We can extend this functionality by creating pagination. This
  allows us to meter the return values into set chunks. This is used frequently
  when interacting with a database through a mediating RESTful API. For example to
  return values from endpoints such as:

  ```
  /api/courses?pageNumber=2&pageSize=10
  ```

  To do this you pass two values as query parameters

  ```js
  const pageNumber = 2;
  const pageSize = 10;

  async function getCourses() {
    const courses = await Course.find()
      .skip(pageNumber - 1 * pageSize)
      .limit(pageSize);
    console.log(courses);
  }
  ```

raw_content:
  ---
  tags:
    - mongo-db
    - node-js
    - mongoose
    - databases
  ---

  # Query a Mongo collection with Mongoose

  We now have the following entries in our `courses` collection:

  ```js
  {
    name: 'Python Course',
    author: 'Terry Ogleton',
    tags: [ 'python', 'backend' ],
    isPublished: true,
    _id: new ObjectId("62f4e2527ac4aa2c30d41d23"),
    date: 2022-08-11T11:04:50.750Z,
    __v: 0
  }

  {
    name: 'Javascript Course',
    author: 'Tosh Gnomay',
    tags: [ 'js', 'frontend' ],
    isPublished: true,
    _id: new ObjectId("62f4e2527ac4aa2c30d41d24"),
    date: 2022-08-11T11:04:50.750Z,
    __v: 0
  }

  ```

  Now we will query the collection. This capability is provided via the Mongoose
  schema class we used to create the `Course`
  [model](Create_collections_and_documents_with_Mongoose.md#models).
  We have the following methods available to use from the schema:

  - `find`
  - `findById`
  - `findByIdAndRemove`
  - `findByIdAndUpdate`
  - `findOne`
  - `findOneAndUpdate`
  - `findOneAndRemove`
  - ...

  The various `find` methods return a value that is promisified.

  ## Return values with `find`

  ```js
  async function getCourses() {
    const courses = await Course.find();
    console.log(courses);
  }
  ```

  ## Filter values returned

  This will return all the published courses where Tosh Gnomay is the author:

  ```js
  async function getCourses() {
    const courses = await Course.find({
      author: "Tosh Gnomay",
      isPublished: true,
    });
    console.log(courses);
  }
  ```

  This time we will filter by the same author but we will add additional
  parameters to distinguish:

  - only the first ten entries (using `.limit(10)`)
  - sort ascending by name (using `.sort({name: 1}))` , to descend we would use
    `-1`)
  - only return the properties `name` and `tags` for the item in the collection
    (using `.select({name: 1, tags: 1})`)

  ```js
  async function getCourses() {
    const courses = await Course.find({
      author: "Tosh Gnomay",
      isPublished: true,
    })
      .limit(10)
      .sort({ name: 1 })
      .select({ name: 1, tags: 1 });
    console.log(courses);
  }
  ```

  This returns:

  ```js
  [
    {
      _id: new ObjectId("62f4f07a875cff48827b8731"),
      name: "Java Course",
      tags: ["java", "backend"],
    },
    {
      _id: new ObjectId("62f4e2527ac4aa2c30d41d24"),
      name: "Javascript Course",
      tags: ["js", "frontend"],
    },
  ];
  ```

  > Note that the UUID is always returned, whether we specify it or not.

  ## Querying with operators

  So far when filtering we have been doing so with reference to properties that
  exist on the document's model (`author`, `isPublished` etc) and we have applied
  tranformations on the data returned (sorting, limiting the number or matches
  etc.). However we can also apply **operators** within our queries. Operators
  allow us to perform computations on the data, for example: for a given numerical
  property on an object, return the objects for which this value is within a
  certain range.

  When we apply operators we use the `$` symbol before the operator and pass the
  operator function as an object.

  The schema:

  ```
  Model.find( { property: { $operator: conditions } } )
  ```

  ### Comparison operators

  The following comparison operators are available in MongoDB:

  | Operator | Function                  |
  | -------- | ------------------------- |
  | `eq`     | Equal to                  |
  | `ne`     | Not equal to              |
  | `gt`     | Greater than              |
  | `gte`    | Greater than or less than |
  | `lt`     | Less than                 |
  | `lte`    | Less than or equal to     |
  | `in`     | In                        |
  | `nin`    | Not in                    |

  We can employ these comparators within a `.find` filter. For example let's
  imagine that our `courses` instances have a property of `price`.

  To filter course prices that are greater than or equal to 10 and less than or
  equal to 29:

  ```js
  Course.find({ price: { $gte: 10, $lte: 20 } });
  ```

  To filter course prices that are either 10, 15 or 20:

  ```js
  Course.find({ price: { $in: [10, 15, 20] } });
  ```

  ### Logical operators

  When we apply logical operators, we do not apply the query within the main
  `find` method. We use a dedicated method that corresponds to the logical
  predicate.

  For example to query by logical
  [OR](Truth-functional_connectives.md#disjunction):

  ```js
  async function getCourses() {
    const courses = await Course.find().or([
      { author: "Tosh Gnomay" },
      { isPublished: true },
    ]);
    console.log(courses);
  }
  ```

  We write each disjunct as an object representing the conditions we are filtering
  for within an array that is passed to the `.or()` method.

  The same syntax applies for conjunction.

  ### Regular expressions

  When filtering by strings we can use Regex for greater power.

  Previously we filtered by the author name:

  ```js
  .find({author: "Tosh Gnomay"})
  ```

  To demonstrate regex we could filter by names beginning with `T`:

  ```js
  .find({author: /^T*/})
  ```

  ```js
  async function getCourses() {
    const courses = await Course.find()
      .or([{ author: "Tosh Gnomay" }, { isPublished: true }])
      .count();
    console.log(courses);
  }
  ```

  This will return a number.

  ### Pagination

  We previously used the `limit()` method to control how many matches we return
  from a query. We can extend this functionality by creating pagination. This
  allows us to meter the return values into set chunks. This is used frequently
  when interacting with a database through a mediating RESTful API. For example to
  return values from endpoints such as:

  ```
  /api/courses?pageNumber=2&pageSize=10
  ```

  To do this you pass two values as query parameters

  ```js
  const pageNumber = 2;
  const pageSize = 10;

  async function getCourses() {
    const courses = await Course.find()
      .skip(pageNumber - 1 * pageSize)
      .limit(pageSize);
    console.log(courses);
  }
  ```


path: zk/React_Components.md
sortable_path: zkReact_Components.md
title: Components
checksum: 04a9cd1e4e18d7f291d2c48096e3d854b6072eb7a441f18682e47a0046861369
created: 2024-06-16 17:06:09.254576843+00:00
modified: 2024-03-27 10:45:52.500191986+00:00
metadata: {"tags":["typescript","react"]}
lead:
  We write functional components in the manner of a normal
  [function](Functions.md) that take
  a props argument and return a JSX element.

body:
  We write functional components in the manner of a normal
  [function](Functions.md) that take
  a props argument and return a JSX element.

  ```jsx
  interface IProps = {
    message: string;
  };
  const App = ({message}: IProps): JSX.Element => <div>{message}</div>;
  ```

  ## `React.FunctionComponent` / `React.FC`

  It used to be the case that you would type a function component like so:

  ```jsx
  const App: React.FunctionComponent<{ message: string }> = ({ message }) => (
    <div>{message}</div>
  );
  ```

  This is now discouraged as it means the component can always accept children,
  even when you do not want this to be the case. There are several other minor
  drawerbacks but it's generally best to leave out the declaration.

raw_content:
  ---
  tags:
    - typescript
    - react
  ---

  # Components

  We write functional components in the manner of a normal
  [function](Functions.md) that take
  a props argument and return a JSX element.

  ```jsx
  interface IProps = {
    message: string;
  };
  const App = ({message}: IProps): JSX.Element => <div>{message}</div>;
  ```

  ## `React.FunctionComponent` / `React.FC`

  It used to be the case that you would type a function component like so:

  ```jsx
  const App: React.FunctionComponent<{ message: string }> = ({ message }) => (
    <div>{message}</div>
  );
  ```

  This is now discouraged as it means the component can always accept children,
  even when you do not want this to be the case. There are several other minor
  drawerbacks but it's generally best to leave out the declaration.


path: zk/React_errors.md
sortable_path: zkReact_errors.md
title: Errors
lead: ## State update on unmounted component
checksum: cfd6611ef29f02dc1c797220a7aa7235d5101356ad8dbe51db45b22375dd90c2
created: 2024-06-16 17:06:09.264356638+00:00
modified: 2024-06-15 10:16:35.863991084+00:00
metadata: {"tags":["javascript","react"]}
body:
  ## State update on unmounted component

  > Can't perform a React state update on an unmounted component. This is a no-op,
  > but it indicates a memory leak in your application. To fix, cancel all
  > subscriptions and asynchronous tasks in a useEffect cleanup function.

  This typically happens when you have an API request running in the background.
  Once the data is returned, React tries to update the state but the component is
  unmounted.

  As the warning suggests, this can be resolved using the cleanup parameter within
  [React_useEffect](React_useEffect.md#cleanup-functions).

raw_content:
  ---
  tags:
    - javascript
    - react
  ---

  # Errors

  ## State update on unmounted component

  > Can't perform a React state update on an unmounted component. This is a no-op,
  > but it indicates a memory leak in your application. To fix, cancel all
  > subscriptions and asynchronous tasks in a useEffect cleanup function.

  This typically happens when you have an API request running in the background.
  Once the data is returned, React tries to update the state but the component is
  unmounted.

  As the warning suggests, this can be resolved using the cleanup parameter within
  [React_useEffect](React_useEffect.md#cleanup-functions).


path: zk/React_useContext.md
sortable_path: zkReact_useContext.md
title: useContext
checksum: 18e785c75ecf5aa0804e9a60c86298bcdcf08758a91c45326c6ae1dc5ccf90ba
created: 2024-06-16 17:06:09.27996053+00:00
modified: 2024-06-15 10:16:24.273746117+00:00
metadata: {"tags":["javascript","react"]}
lead:
  We use React's Context API to enable us to easily share stateful data between
  all levels of an application without having to use repetitious 'prop-drilling'
  at a component level.

body:
  We use React's Context API to enable us to easily share stateful data between
  all levels of an application without having to use repetitious 'prop-drilling'
  at a component level.

  This works best with data that is global by definition, such as theme parameters
  or access authorisation. Context should not be used when standard and proximate
  compositional methods and prop-passing are sufficient.

  ## Providers and consumers

  The Context API preceded the introduction of hooks in React 16.8 and it still
  underpins context management in hooks, although the syntax is simplified.

  The process is as follows:

  - Initiate a context
  - Create a parent `Provider` component that owns the data that will be passed
    down
  - Create child `Consumer` components that receive the data of the parent.

  We will demonstrate using a set of styles as the context that we want to pass
  around our app.

  ```jsx
  const style = {
    border: "2px solid dodgerblue",
    background: "lightblue",
    color: "dodgerblue",
  };
  ```

  Le's initiate a context:

  ```jsx
  const StyleContext = React.createContext();
  ```

  Now that we have our data and have initialized a context, we can apply it to our
  app components:

  ```jsx
  <StyleContext.Provider value={style}>...</StyleContext.Provider>
  ```

  This is the parent element of the context environment. This stores the
  contextual data as a prop. Next we need to make a component that acts as the
  consumer of this data. Let's create this component and call it `Child` for
  simplicity:

  ```jsx
  const Child = () => {
    return (
      <StyleContext.Consumer>
        {(value) => (
          <div style={value}>
            <p>
              I'm a <b>child</b>. I <b>consume</b> of the data my parent provides.
            </p>
          </div>
        )}
      </StyleContext.Consumer>
    );
  };
  ```

  The contents of this component are wrapped in tags that reference the specific
  context (`StyleContext`) and the role that the component plays: `Consumer`.

  We are taking the `value` prop owned by `StyleContext.Provider` and passing it
  to the wrapping component of `Child` as a `style` tag. This means that `Child`
  will display these styles.

  The final step is just to insert our `<Child />` components beneath the parent
  component, e.g.:

  ```jsx
  <StyleContext.Provider value={style}>
    <Child />
    <Child />
  </StyleContext.Provider>
  ```

  ## `useContext` hook

  The hook removes the need to explicitly declare `Provider` and `Consumer`
  components; their role becomes more implicit.

  To demonstrate let's use a different example. We are going to have a single
  integer as the data context, `42`.

  First invoke and intialize the Context API, just as before:

  ```jsx
  const NumberContext = React.createContext(42);
  ```

  Next, we just need to create our provider component. We don't have to worry
  about a consumer since this is handled implicitly by the invocation of the hook

  ```jsx
  const Context = () => {
    const data = useContext(NumberContext);
    return <Typography>{data}</Typography>;
  };
  ```

  Then, in our code we just insert the `Context` component:

  ```jsx
  <Context>...</Context>
  ```

  ## Updating context state

  In the examples above we have only been consuming state that is owned by the
  provider however in most scenarios you will also want to update the state from a
  consumer. This is best achieved by combining `useContext` with a reducer and is
  detailed in [Application state management](Application_state_management_with_React_hooks.md).

raw_content:
  ---
  tags:
    - javascript
    - react
  ---

  # `useContext`

  We use React's Context API to enable us to easily share stateful data between
  all levels of an application without having to use repetitious 'prop-drilling'
  at a component level.

  This works best with data that is global by definition, such as theme parameters
  or access authorisation. Context should not be used when standard and proximate
  compositional methods and prop-passing are sufficient.

  ## Providers and consumers

  The Context API preceded the introduction of hooks in React 16.8 and it still
  underpins context management in hooks, although the syntax is simplified.

  The process is as follows:

  - Initiate a context
  - Create a parent `Provider` component that owns the data that will be passed
    down
  - Create child `Consumer` components that receive the data of the parent.

  We will demonstrate using a set of styles as the context that we want to pass
  around our app.

  ```jsx
  const style = {
    border: "2px solid dodgerblue",
    background: "lightblue",
    color: "dodgerblue",
  };
  ```

  Le's initiate a context:

  ```jsx
  const StyleContext = React.createContext();
  ```

  Now that we have our data and have initialized a context, we can apply it to our
  app components:

  ```jsx
  <StyleContext.Provider value={style}>...</StyleContext.Provider>
  ```

  This is the parent element of the context environment. This stores the
  contextual data as a prop. Next we need to make a component that acts as the
  consumer of this data. Let's create this component and call it `Child` for
  simplicity:

  ```jsx
  const Child = () => {
    return (
      <StyleContext.Consumer>
        {(value) => (
          <div style={value}>
            <p>
              I'm a <b>child</b>. I <b>consume</b> of the data my parent provides.
            </p>
          </div>
        )}
      </StyleContext.Consumer>
    );
  };
  ```

  The contents of this component are wrapped in tags that reference the specific
  context (`StyleContext`) and the role that the component plays: `Consumer`.

  We are taking the `value` prop owned by `StyleContext.Provider` and passing it
  to the wrapping component of `Child` as a `style` tag. This means that `Child`
  will display these styles.

  The final step is just to insert our `<Child />` components beneath the parent
  component, e.g.:

  ```jsx
  <StyleContext.Provider value={style}>
    <Child />
    <Child />
  </StyleContext.Provider>
  ```

  ## `useContext` hook

  The hook removes the need to explicitly declare `Provider` and `Consumer`
  components; their role becomes more implicit.

  To demonstrate let's use a different example. We are going to have a single
  integer as the data context, `42`.

  First invoke and intialize the Context API, just as before:

  ```jsx
  const NumberContext = React.createContext(42);
  ```

  Next, we just need to create our provider component. We don't have to worry
  about a consumer since this is handled implicitly by the invocation of the hook

  ```jsx
  const Context = () => {
    const data = useContext(NumberContext);
    return <Typography>{data}</Typography>;
  };
  ```

  Then, in our code we just insert the `Context` component:

  ```jsx
  <Context>...</Context>
  ```

  ## Updating context state

  In the examples above we have only been consuming state that is owned by the
  provider however in most scenarios you will also want to update the state from a
  consumer. This is best achieved by combining `useContext` with a reducer and is
  detailed in [Application state management](Application_state_management_with_React_hooks.md).


path: zk/React_useEffect.md
sortable_path: zkReact_useEffect.md
title: useEffect
checksum: 51bb0ac90d0fe8ea36cf7558d565e1952a742fea7607da793b900f2635046711
created: 2024-06-16 17:06:09.292170726+00:00
modified: 2024-06-15 10:16:34.707300001+00:00
metadata: {"tags":["javascript","react"]}
lead:
  `useEffect` should be used for any background process that does not arise as a
  result of a user interaction or standard state change. The canonical example
  would be dispatching a request to an API to retrieve data to display in a
  component's initial render.

body:
  `useEffect` should be used for any background process that does not arise as a
  result of a user interaction or standard state change. The canonical example
  would be dispatching a request to an API to retrieve data to display in a
  component's initial render.

  `useEffect` enshrines but also simplifies the
  [lifecyle methods](Lifecycle_methods.md) that are used with
  class-based React components.

  ## Demonstration

  ```jsx
  const [workflowTitle, setWorkflowTitle] = useState("");
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    const fetchWorkflowTitle = () => {
      axios
        .post(`${process.env.REACT_APP_ENDPOINT}/load-workflows`, {
          workflow_id: project_id,
          user_id: isAuth?.userId,
        })
        .then((res) => {
          setWorkflowTitle(res?.data?.meta.name);
        })
        .finally(() => setLoading(false))
        .catch((err) => {
          console.error(err);
        });
    };
    setLoading(true);
    fetchWorkflowTitle();
  }, [project_id, isAuth]);
  ```

  In this example we fetch some data from a REST API and store the response value
  as state, which can then be accessed within our JSX template.

  ## Function placement

  In the example, the function is declared inside of the `useEffect` hook and then
  called. We do this to avoid adding the function to the dependency array, which
  we couldn't do if we defined it outside of the hook, somewhere in the component.
  If we did this, the function would run on every render by default and would be
  recalled again because of its placement in the dependency array, which leads to
  the 'too many rerenders' error.

  An alternative would be to define it outside of the component itself but this is
  difficult since it requires state from the component to run.

  ## Dependency array

  Note the array that is the second argument to `useEffect`. This is the
  **dependency array** and is how we manage the lifecycle of the side-effect.

  - After the initial call on render, the function within the `useEffect` block
    will run any time one of the dependencies update. The dependency array
    typically refers to variables that are defined within the hook but can also
    contain references to variables outside of it.

  - If you do not include the array, the effect runs on every render

  - If you pass an empty array, the effect will only run once on the initial
    render

  ## Cleanup functions

  The syntax of the `useEffect` hook also allows you to handle cleanup: something
  you want to do when the component unmounts (another example of how this hook
  recasts the traditional [lifecycle methods](Lifecycle_methods.md))
  . In addition to running on unmount, the cleanup function will run before the
  effect runs again (i.e. when it runs in response to a change in one of the
  elements of the dependency araray). This is chiefly used to prevent
  [memory leaks](Memory_leaks.md) and the
  ['update on unmounted component error'](React_errors.md#state-update-on-unmounted-component).

  You do this by having a `return` clause after the main effect. Schematically:

  ```js
  useEffect(() => {
    //  Run your effect;
    return () => {
      //   Put your cleanup function here
    };
  }, [input]);
  ```

  Here is an example of using a cleanup to cancel a subscription

  ```js
  useEffect(() => {
    let isApiSubscribed = true;
    axios.get(API).then((response) => {
      if (isApiSubscribed) {
        // handle success
      }
    });
    return () => {
      isApiSubscribed = false;
    };
  }, []);
  ```

  ## Resources

  [Understanding the React useEffect cleanup function]()

raw_content:
  ---
  tags:
    - javascript
    - react
  ---

  # `useEffect`

  `useEffect` should be used for any background process that does not arise as a
  result of a user interaction or standard state change. The canonical example
  would be dispatching a request to an API to retrieve data to display in a
  component's initial render.

  `useEffect` enshrines but also simplifies the
  [lifecyle methods](Lifecycle_methods.md) that are used with
  class-based React components.

  ## Demonstration

  ```jsx
  const [workflowTitle, setWorkflowTitle] = useState("");
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    const fetchWorkflowTitle = () => {
      axios
        .post(`${process.env.REACT_APP_ENDPOINT}/load-workflows`, {
          workflow_id: project_id,
          user_id: isAuth?.userId,
        })
        .then((res) => {
          setWorkflowTitle(res?.data?.meta.name);
        })
        .finally(() => setLoading(false))
        .catch((err) => {
          console.error(err);
        });
    };
    setLoading(true);
    fetchWorkflowTitle();
  }, [project_id, isAuth]);
  ```

  In this example we fetch some data from a REST API and store the response value
  as state, which can then be accessed within our JSX template.

  ## Function placement

  In the example, the function is declared inside of the `useEffect` hook and then
  called. We do this to avoid adding the function to the dependency array, which
  we couldn't do if we defined it outside of the hook, somewhere in the component.
  If we did this, the function would run on every render by default and would be
  recalled again because of its placement in the dependency array, which leads to
  the 'too many rerenders' error.

  An alternative would be to define it outside of the component itself but this is
  difficult since it requires state from the component to run.

  ## Dependency array

  Note the array that is the second argument to `useEffect`. This is the
  **dependency array** and is how we manage the lifecycle of the side-effect.

  - After the initial call on render, the function within the `useEffect` block
    will run any time one of the dependencies update. The dependency array
    typically refers to variables that are defined within the hook but can also
    contain references to variables outside of it.

  - If you do not include the array, the effect runs on every render

  - If you pass an empty array, the effect will only run once on the initial
    render

  ## Cleanup functions

  The syntax of the `useEffect` hook also allows you to handle cleanup: something
  you want to do when the component unmounts (another example of how this hook
  recasts the traditional [lifecycle methods](Lifecycle_methods.md))
  . In addition to running on unmount, the cleanup function will run before the
  effect runs again (i.e. when it runs in response to a change in one of the
  elements of the dependency araray). This is chiefly used to prevent
  [memory leaks](Memory_leaks.md) and the
  ['update on unmounted component error'](React_errors.md#state-update-on-unmounted-component).

  You do this by having a `return` clause after the main effect. Schematically:

  ```js
  useEffect(() => {
    //  Run your effect;
    return () => {
      //   Put your cleanup function here
    };
  }, [input]);
  ```

  Here is an example of using a cleanup to cancel a subscription

  ```js
  useEffect(() => {
    let isApiSubscribed = true;
    axios.get(API).then((response) => {
      if (isApiSubscribed) {
        // handle success
      }
    });
    return () => {
      isApiSubscribed = false;
    };
  }, []);
  ```

  ## Resources

  [Understanding the React useEffect cleanup function]()


path: zk/React_useReducer.md
sortable_path: zkReact_useReducer.md
title: useReducer
checksum: 4600c79d0f79238fef08e60c2bc5e34d201e5ecba7070140155aef074d9e749c
created: 2024-06-16 17:06:09.316154908+00:00
modified: 2024-06-15 10:17:04.28125543+00:00
metadata: {"tags":["javascript","react"]}
lead:
  The `useReducer` hook is best used in scenarios where you are manipulating state
  in a way that is too complex for the trivial [React_useState](React_useState.md) use case.
  `useState` is best employed when you are updating a single value or toggling a
  boolean. If you are updating the state of an object or more complex data
  structure, it is often more efficient to employ `useReducer`.

body:
  The `useReducer` hook is best used in scenarios where you are manipulating state
  in a way that is too complex for the trivial [React_useState](React_useState.md) use case.
  `useState` is best employed when you are updating a single value or toggling a
  boolean. If you are updating the state of an object or more complex data
  structure, it is often more efficient to employ `useReducer`.

  This makes the code more manageable and also helps with separating state
  management from rendering.

  ## Syntax

  ```jsx
  const [state, dispatch] = useReducer(reducer, initialState);
  ```

  - `initialState`
    - The starting state, typically an object
  - `reducer`
    - A pure function that accepts two parameters:
      - The current state
      - An action object
    - The reducer function must update the current state (immutably) and return
      the new state
    - We can think of the reducer as working in the same manner as
      `state`/`setState` in the `useState` hook. The functional role is the same,
      it is just that the reducer offers more than one type of update.

  ### Example reducer

  ```js
  function reducer(state, action) {
    let newState;
    switch (action.type) {
      case "increase":
        newState = { counter: state.counter + 1 };
        break;
      case "descrease":
        newState = { counter: state.counter - 1 };
        break;
      default:
        throw new Error();
    }
    return newState;
  }
  ```

  In this example we are updating an object with the following shape:

  ```js
  {
      counter: 0,
  }
  ```

  This would be the `initialState` that we pass to the `useReducer` hook along
  with a reference to `reducer` above.

  To update the state we would invoke the `dispatch` function which applies one of
  the actions defined in the reducer. For example the following dispatch
  increments the counter by one:

  ```js
  dispatch({ type: "increase" });
  ```

  To view the updated value:

  ```js
  console.log(state.counter);
  ```

  ### Refining the syntax

  Because React doesn't mutate state, the reducer doesn't directly modify the
  current state in the `state` variable, it creates a new instance of the state
  object on each update.

  In the reducer example above this is achieved by declaring a variable `newState`
  that is updated by each `action` type and then returned. There is a more elegant
  way of doing this using spread syntax:

  ```js
  function reducer(state, action) {
    switch (action.type) {
      case "increase":
        return { ...state, counter: state.counter + 1 };
        break;
      case "decrease":
        return { ...state, counter: state.counter - 1 };
        break;
      default:
        throw new Error();
    }
  }
  ```

  ### Including payloads

  In the examples so far, we have updated the the state directly via the action
  type however it is also possible to pass data along with the `action.type` as
  `action.payload`.

  For example:

  ```js
  dispatch(
    {
      type: 'increase_by_payload'
      payload: 3,
    });
  ```

  Then we would update our reducer to handle this case:

  ```js
  function reducer(state, action) {
    switch (action.type) {
      ...
      case 'increase_by_payload':
      return {...state, counter: state.counter + action.payload}
      default:
        throw new Error();
    }
  }
  ```

raw_content:
  ---
  tags:
    - javascript
    - react
  ---

  # `useReducer`

  The `useReducer` hook is best used in scenarios where you are manipulating state
  in a way that is too complex for the trivial [React_useState](React_useState.md) use case.
  `useState` is best employed when you are updating a single value or toggling a
  boolean. If you are updating the state of an object or more complex data
  structure, it is often more efficient to employ `useReducer`.

  This makes the code more manageable and also helps with separating state
  management from rendering.

  ## Syntax

  ```jsx
  const [state, dispatch] = useReducer(reducer, initialState);
  ```

  - `initialState`
    - The starting state, typically an object
  - `reducer`
    - A pure function that accepts two parameters:
      - The current state
      - An action object
    - The reducer function must update the current state (immutably) and return
      the new state
    - We can think of the reducer as working in the same manner as
      `state`/`setState` in the `useState` hook. The functional role is the same,
      it is just that the reducer offers more than one type of update.

  ### Example reducer

  ```js
  function reducer(state, action) {
    let newState;
    switch (action.type) {
      case "increase":
        newState = { counter: state.counter + 1 };
        break;
      case "descrease":
        newState = { counter: state.counter - 1 };
        break;
      default:
        throw new Error();
    }
    return newState;
  }
  ```

  In this example we are updating an object with the following shape:

  ```js
  {
      counter: 0,
  }
  ```

  This would be the `initialState` that we pass to the `useReducer` hook along
  with a reference to `reducer` above.

  To update the state we would invoke the `dispatch` function which applies one of
  the actions defined in the reducer. For example the following dispatch
  increments the counter by one:

  ```js
  dispatch({ type: "increase" });
  ```

  To view the updated value:

  ```js
  console.log(state.counter);
  ```

  ### Refining the syntax

  Because React doesn't mutate state, the reducer doesn't directly modify the
  current state in the `state` variable, it creates a new instance of the state
  object on each update.

  In the reducer example above this is achieved by declaring a variable `newState`
  that is updated by each `action` type and then returned. There is a more elegant
  way of doing this using spread syntax:

  ```js
  function reducer(state, action) {
    switch (action.type) {
      case "increase":
        return { ...state, counter: state.counter + 1 };
        break;
      case "decrease":
        return { ...state, counter: state.counter - 1 };
        break;
      default:
        throw new Error();
    }
  }
  ```

  ### Including payloads

  In the examples so far, we have updated the the state directly via the action
  type however it is also possible to pass data along with the `action.type` as
  `action.payload`.

  For example:

  ```js
  dispatch(
    {
      type: 'increase_by_payload'
      payload: 3,
    });
  ```

  Then we would update our reducer to handle this case:

  ```js
  function reducer(state, action) {
    switch (action.type) {
      ...
      case 'increase_by_payload':
      return {...state, counter: state.counter + action.payload}
      default:
        throw new Error();
    }
  }
  ```


path: zk/React_useState.md
sortable_path: zkReact_useState.md
title: useState
checksum: e3bc20741b5029e4be18e645b02bae622e038b3e40b6f60627620481e4a59686
created: 2024-06-16 17:06:09.331234913+00:00
modified: 2024-06-15 10:16:47.17756286+00:00
metadata: {"tags":["javascript","react"]}
lead:
  `useState` is the primary way in which React updates the application state based
  on user interaction.

body:
  `useState` is the primary way in which React updates the application state based
  on user interaction.

  - `useState` **receives**: the initial state as an argument
  - `useState` **returns**: the current state and a function that updates it

  The two items that are returned are returned as an array. We could refer to them
  with array syntax (i.e with `[0]` and `[1]` ) but it is more concise to use the
  destructuring syntax. But all that's happening is that a method belonging to the
  `React` library (i.e. `useState` ) is taking an argument (the initial state) and
  returning two values as an array of two elements. The first of these values is a
  variable, the second is a function.

  ```jsx
  (1) const [count, setCount] = useState(0);
  (2) const handleClick = () => { setCount(count + 1) };

  (3) <span>{count}</span>
  (4) <button onClick={handleClick)>Add one</button>
  ```

  - At line 1 we initialise the `useState` hook.
    - We use destructuring syntax to declare two variables
    - The first variable stores our initial state. The value of the initial state
      is an argument passed to `useState` , i.e. `0`. Do not confuse the variable
      with the value it refers to.
    - The second variable is a method that mutates the state referred to by the
      first variable into some new value, i.e. from `0` to a different integer
  - At line 3, which in reality, will be within your JSX and part of the
    `render()` block of the function, we render the initial state in the React
    DOM. This will change and be re-rendered in accordance with the state logic
  - At line 4 we have a user interface that executes the function on line 2. This
    function applies the state change represented by the second variable in the
    destructuring assignment at line 1 (`setCount` ): it mutates the initial state
    (`0`) by the value of `1'.

  > You can utilise as many `useState` declarations as your component requires.

  ## Passing variables as initial state

  We don't always have to declare the data types within the destructuring
  assignment. We can store them in variables and pass the variables to the
  destructuring assignment on `useState` . Below we do this for a function that
  mutates a string value:

  ```jsx
  const hi = "hello";
  const bye = "goodbye";

  const [initText, changeText] = useState(hi);

  <p>{initText}</p>
  <button onClick={()=>changeText(bye)}>ChangeText</button>
  ```

  ## Lazily setting initial state

  Although you will typically use a literal value or variable as your initial
  state, React provides a way for you to set this value through a function. This
  will only run once at the first render so as not to interfere with the second
  update parameter of `useState`. This is called **lazy initialisation**

  ```jsx
  const getInitialState = () => Number(window.localStorage.getItem("count"));
  const [count, setCount] = React.useState(getInitialState);
  ```

  ## Accessing previous state

  It is also possible to access the previous state via the `useState` hook. We can
  access this as a callback on the updater function.

  Let's say we have a simple counter set up like so:

  ```js
  const [count, setCount] = useState(0);
  ```

  We can access the prior value of `count` with:

  ```js
  const getPrevValue = () => setCount((prev) => console.log(prev));
  ```

  ### Naming best practise

  When destructuring the two variables from `useState`, React follows uses the
  following semantics: `[something, setSomething]` . This isn't required but it
  helps to keep everything clear, particularly the fact that the first thing
  destructured is a variable and the second is a function.

  > https://stackoverflow.com/questions/54807454/what-is-prevstate-in-reactjs

raw_content:
  ---
  tags:
    - javascript
    - react
  ---

  # `useState`

  `useState` is the primary way in which React updates the application state based
  on user interaction.

  - `useState` **receives**: the initial state as an argument
  - `useState` **returns**: the current state and a function that updates it

  The two items that are returned are returned as an array. We could refer to them
  with array syntax (i.e with `[0]` and `[1]` ) but it is more concise to use the
  destructuring syntax. But all that's happening is that a method belonging to the
  `React` library (i.e. `useState` ) is taking an argument (the initial state) and
  returning two values as an array of two elements. The first of these values is a
  variable, the second is a function.

  ```jsx
  (1) const [count, setCount] = useState(0);
  (2) const handleClick = () => { setCount(count + 1) };

  (3) <span>{count}</span>
  (4) <button onClick={handleClick)>Add one</button>
  ```

  - At line 1 we initialise the `useState` hook.
    - We use destructuring syntax to declare two variables
    - The first variable stores our initial state. The value of the initial state
      is an argument passed to `useState` , i.e. `0`. Do not confuse the variable
      with the value it refers to.
    - The second variable is a method that mutates the state referred to by the
      first variable into some new value, i.e. from `0` to a different integer
  - At line 3, which in reality, will be within your JSX and part of the
    `render()` block of the function, we render the initial state in the React
    DOM. This will change and be re-rendered in accordance with the state logic
  - At line 4 we have a user interface that executes the function on line 2. This
    function applies the state change represented by the second variable in the
    destructuring assignment at line 1 (`setCount` ): it mutates the initial state
    (`0`) by the value of `1'.

  > You can utilise as many `useState` declarations as your component requires.

  ## Passing variables as initial state

  We don't always have to declare the data types within the destructuring
  assignment. We can store them in variables and pass the variables to the
  destructuring assignment on `useState` . Below we do this for a function that
  mutates a string value:

  ```jsx
  const hi = "hello";
  const bye = "goodbye";

  const [initText, changeText] = useState(hi);

  <p>{initText}</p>
  <button onClick={()=>changeText(bye)}>ChangeText</button>
  ```

  ## Lazily setting initial state

  Although you will typically use a literal value or variable as your initial
  state, React provides a way for you to set this value through a function. This
  will only run once at the first render so as not to interfere with the second
  update parameter of `useState`. This is called **lazy initialisation**

  ```jsx
  const getInitialState = () => Number(window.localStorage.getItem("count"));
  const [count, setCount] = React.useState(getInitialState);
  ```

  ## Accessing previous state

  It is also possible to access the previous state via the `useState` hook. We can
  access this as a callback on the updater function.

  Let's say we have a simple counter set up like so:

  ```js
  const [count, setCount] = useState(0);
  ```

  We can access the prior value of `count` with:

  ```js
  const getPrevValue = () => setCount((prev) => console.log(prev));
  ```

  ### Naming best practise

  When destructuring the two variables from `useState`, React follows uses the
  following semantics: `[something, setSomething]` . This isn't required but it
  helps to keep everything clear, particularly the fact that the first thing
  destructured is a variable and the second is a function.

  > https://stackoverflow.com/questions/54807454/what-is-prevstate-in-reactjs


path: zk/Update_a_Mongo_document.md
sortable_path: zkUpdate_a_Mongo_document.md
title: Update a MongoDB document
lead: There are two methods for updating a document
checksum: 45e294432528520811c33744708746297fb71bfdc96726da610ef0146c820ba4
created: 2024-06-16 17:06:09.560781628+00:00
modified: 2024-06-15 10:04:40.389014679+00:00
metadata: {"tags":["mongo-db","node-js","mongoose","databases"]}
body:
  There are two methods for updating a document

  - query first
  - update first

  ## Query first document update

  With this approach we first execute a
  [query](Querying_a_Mongo_collection.md) to retrieve the document we
  want to edit and then make the change. We use the `findById` method to identify
  the document by its UUID and then `set` to update specified properties on the
  document. The `set` method is one of many operators that can be used to update
  values. For example there is also built-in operators for increment, renaming,
  multiplying values.

  Query first is best used when you want to secure the update with some prior
  logic or to validate. For example you may not want to update a course if it is
  listed as published. You could use a query to determine the publish status and
  then only update the entry if it returns `isPublished: false`.

  ```js
  async function updateCourseFromQuery(id) {
    const course = await Course.findById(id);
    if (!course) return;
    course.set({
      isPublished: true,
      author: "A new author",
    });

    // Instead of an object, we could also set the updated properties individually
    course.isPublished = true;
    course.author = "Biggs Volunksire";

    const result = course.save();
    console.log(result);
  }
  ```

  ## Update first document update

  With this approach we don't bother with a prior query. We are confident that the
  update is legitimate and do not need to first determine that certain conditions
  are met.

  To do this we directly use the `update` method, not `find`:

  ```js
  async function updateCourseFromQuery(id) {
    const result = await Course.update({ _id: id });
    $set: {
      // Invoke the set operator
      author: "Terry Nutile";
      isPublished: true;
    }
    console.log(result);
  }
  ```

  This function will just return some metadata about the update. It won't by
  default return the updated value. To do this use the `findByIdAndUpdate()`
  method instead of `update`:

  ```js
  async function updateCourseFromQuery(id) {
      const course = await Course.findByIdAndUpdate(id, {
      $set: { // Invoke the set operator
          author: 'Terry Nutile'
          isPublished: true
      }, {new: true}});
      console.log(result)
  }
  ```

  If we don't add `{new: true}`, it will return the document before the update.

  ### Updating multiple documents at once

  // Add: notes on this

raw_content:
  ---
  tags:
    - mongo-db
    - node-js
    - mongoose
    - databases
  ---

  # Update a MongoDB document

  There are two methods for updating a document

  - query first
  - update first

  ## Query first document update

  With this approach we first execute a
  [query](Querying_a_Mongo_collection.md) to retrieve the document we
  want to edit and then make the change. We use the `findById` method to identify
  the document by its UUID and then `set` to update specified properties on the
  document. The `set` method is one of many operators that can be used to update
  values. For example there is also built-in operators for increment, renaming,
  multiplying values.

  Query first is best used when you want to secure the update with some prior
  logic or to validate. For example you may not want to update a course if it is
  listed as published. You could use a query to determine the publish status and
  then only update the entry if it returns `isPublished: false`.

  ```js
  async function updateCourseFromQuery(id) {
    const course = await Course.findById(id);
    if (!course) return;
    course.set({
      isPublished: true,
      author: "A new author",
    });

    // Instead of an object, we could also set the updated properties individually
    course.isPublished = true;
    course.author = "Biggs Volunksire";

    const result = course.save();
    console.log(result);
  }
  ```

  ## Update first document update

  With this approach we don't bother with a prior query. We are confident that the
  update is legitimate and do not need to first determine that certain conditions
  are met.

  To do this we directly use the `update` method, not `find`:

  ```js
  async function updateCourseFromQuery(id) {
    const result = await Course.update({ _id: id });
    $set: {
      // Invoke the set operator
      author: "Terry Nutile";
      isPublished: true;
    }
    console.log(result);
  }
  ```

  This function will just return some metadata about the update. It won't by
  default return the updated value. To do this use the `findByIdAndUpdate()`
  method instead of `update`:

  ```js
  async function updateCourseFromQuery(id) {
      const course = await Course.findByIdAndUpdate(id, {
      $set: { // Invoke the set operator
          author: 'Terry Nutile'
          isPublished: true
      }, {new: true}});
      console.log(result)
  }
  ```

  If we don't add `{new: true}`, it will return the document before the update.

  ### Updating multiple documents at once

  // Add: notes on this


# links

title: Zettelkasten
href: https://en.wikipedia.org/wiki/Zettelkasten
type: markdown
snippet:
  It is a [Zettelkasten](https://en.wikipedia.org/wiki/Zettelkasten) work in
  progress. I've recently converted the topic-based subdirectories into a single
  flat directory structure organised by tags. I'm in the process of partitioning
  longer notes into smaller informational units.


title: zk
href: https://github.com/zk-org/zk
type: markdown
snippet:
  I use the [zk](https://github.com/zk-org/zk) CLI package to help with indexing
  and task automation alongside its [zk-nvim](https://github.com/zk-org/zk-nvim)
  Neovim wrapper. I occassionally utilise [Obsidian](https://obsidian.md/)
  alongside Neovim for when I want to view my notes as a knowledge graph or read
  them alongside their rich content (images, videos etc).


title: dotfiles
href: https://github.com/thomasabishop/dotfiles
type: markdown
snippet:
  Commands are local to my Linux machine, specified in my
  [dotfiles](https://github.com/thomasabishop/dotfiles). They are how I generate
  new entries and manage the knowledge base.


title: Telescope
href: https://github.com/nvim-telescope/telescope.nvim
type: markdown
snippet:
  | Alias          | Command                | Output                                                                                                                       |
  | -------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
  | `z`            | `cd $HOME/repos/eolas` | Access Zettelkasten                                                                                                          |
  | `zn`           | `zk new --title ...`   | Create new entry from template                                                                                               |
  | `<leader> zk`  | `:ZkNotes`             | Access Zettelkasten from anywhere within `nvim`                                                                              |
  | `<leader> zi`  | `:ZkIndex`             | Index Zettelkasten within `nvim`                                                                                             |
  | `<leader> zt`  | `:ZkTags`              | View tags via [Telescope](https://github.com/nvim-telescope/telescope.nvim) within `nvim`                                    |
  | `<leader> ztt` | `:ObsidianTags`        | View tags in a Vim buffer via within `nvim` using [obsidian-nvim](https://github.com/epwalsh/obsidian.nvim)                  |
  | `<leader> zl`  | `:ZkLinks`             | View links in current entry via Telescope within `nvim`, using [obsidian-nvim](https://github.com/epwalsh/obsidian.nvim)     |
  | `<leader> zb`  | `:ZkBacklinks`         | View backlinks to current entry via Telescope within `nvim`, using [obsidian-nvim](https://github.com/epwalsh/obsidian.nvim) |


title: scripts
href: scripts
type: markdown
snippet:
  The [scripts](/scripts) directory contains several Bash and Python scripts I use
  for general housekeeping, such as formatting image URLs, removing unused assets,
  and autosaving.


title: bash script
href: scripts/auto_save.sh
type: markdown
snippet:
  I use a [bash script](./scripts/auto_save.sh) to create autosave functionality
  via Git. This script runs every 15 minutes via a
  [systemd time](https://github.com/thomasabishop/dotfiles/tree/master/systemd/zettelkasten_autosave)
  timer. It tidies up the directory (removes unused images, ensures all file names
  use underscores rather than spaces and hyphens etc) and commits and pushes to
  GitHub.


title: using API Gateway as Lambda trigger
href: zk/Practical_walkthrough_Lambda_creation_within_AWS.md
type: markdown
snippet:
  See
  [using API Gateway as Lambda trigger](Practical_walkthrough_Lambda_creation_within_AWS.md)
  for a basic example of usage.


title: Fetch from Secrets Manager
href: zk/Fetch_from_Secrets_Manager.md
type: markdown
snippet:
  See
  [Fetch from Secrets Manager](Fetch_from_Secrets_Manager.md)
  for a code example of retrieving a value from Secrets Manager.


title: factors and divisors
href: zk/Factors_and_divisors.md
type: markdown
snippet:
  Given the symmetry between
  [factors and divisors](Factors_and_divisors.md) these
  properties are related. Note however that the LCM is more generic: it applies to
  any set of numbers not just fractions. Whereas the LCD is explicitly to do with
  fractions (hence 'denominator').


title: increase the complexity
href: zk/Why_computers_use_binary.md#from-circuits-to-programs
type: markdown
snippet:
  Although a digital system could use more than two symbols, adding more would
  [increase the complexity](Why_computers_use_binary.md#from-circuits-to-programs)
  and cost of the system. A set of only two symbols allows for simplified hardware
  and improved reliability.


title: schema
href: zk/Apollo_Server.md#example-schema
type: markdown
snippet:
  We will be working with the
  > [schema](Apollo_Server.md#example-schema) we defined
  > when working on the server


title: resolver
href: zk/Apollo_Server.md#implementing-resolvers
type: markdown
snippet:
  Therefore, for each query in the schema we must write a frontend implementation.
  We do this with **query constants**. The frontend implementation has a backend
  analogue: the
  [resolver](Apollo_Server.md#implementing-resolvers)
  that is invoked when the frontend issues a query. The schema standardises this
  relationship so that every query on the client must have a corresponding
  resolver on the backend.


title: listener
href: zk/Node_JS_events_module.md#extending-the-eventemitter-class
type: markdown
snippet:
  We instantiate an `ApolloServer` instance and pass our schema to it. We then
  subscribe to it with a
  [listener](Node_JS_events_module.md#extending-the-eventemitter-class).


title: function
href: zk/Creating_a_GraphQL_server.md#resolvers
type: markdown
snippet:
  A resolver is a [function](Creating_a_GraphQL_server.md#resolvers) that
  populates data for a given query. It should have **the same name as the field
  for the query**. So far we have one query in our schema: `tracksForHome` which
  returns the tracks to be listed on the home page. We must therefore also name
  our resolver for this query `tracksForHome`.


title: generic example
href: zk/Creating_a_GraphQL_server.md#resolvers
type: markdown
snippet:
  As per the [generic example](Creating_a_GraphQL_server.md#resolvers), you
  write write your resolvers as keys on a `resolvers` object, e.g:


title: resolver chains
href: zk/Using_arguments_with_Apollo_Client.md#resolver-chains
type: markdown
snippet:
  Used with
      [resolver chains](Using_arguments_with_Apollo_Client.md#resolver-chains)
      ---add example


title: argument
href: zk/Using_arguments_with_Apollo_Client.md
type: markdown
snippet:
  This time we utilise the `args` parameter in the resolver since an `id` will
    be provided as a client-side
    [argument](Using_arguments_with_Apollo_Client.md) to
    return a specific author.


title: Routing
href: zk/Routing.md
type: markdown
snippet:
  If you are using React Router `App` becomes the index for the different page
    components. See [Routing](Routing.md) for more detail.


title: logic gates
href: zk/Logic_gates.md
type: markdown
snippet:
  The ALU comprises
  [logic gates](Logic_gates.md) that
  execute the instructions passed from memory and where the data stored by the
  registers is acted upon. A processor's ALU is just a complex combinatorial logic
  circuit.


title: full-adders and half adders
href: zk/Half_adder_and_full_adder.md
type: markdown
snippet:
  It executes arithmetic and logical operations on binary numbers and where you
  will find operations conducted by
  [full-adders and half adders](Half_adder_and_full_adder.md)
  etc.


title: fetch, decode, execute cycle
href: zk/Fetch_decode_execute.md
type: markdown
snippet:
  More specifically, the ALU is responsible for the _execute_ phase of the
  [fetch, decode, execute cycle](Fetch_decode_execute.md).


title: Basic properties of sets
href: zk/Basic properties of sets.md
type: markdown
snippet:
  The basic notions of set theory are defined in
  [Basic properties of sets](Basic%20properties%20of%20sets.md). There we
  introduced a formal syntax that will be utilised to define the axioms. For easy
  reference:


title: hexadecimal
href: zk/Hexadecimal_number_system.md
type: markdown
snippet:
  To distinguish numbers in binary from decimal or
  [hexadecimal](Hexadecimal_number_system.md)
  numbers, it is common to use the prefix `0b`. Thus, e.g, `0b110` for decimal
  `6`.


title: binary number system
href: zk/Binary_number_system.md
type: markdown
snippet:
  The equivalent entity in the
  [binary number system](Binary_number_system.md)
  is the **bit**. For example the binary number 110 has three bits. A bit can only
  have one of two values in contrast to a digit which can have one of ten values.
  These values are 0 and 1.


title: standard metric prefixes
href: zk/Prefixes_for_units_of_electrical_measurement.md
type: markdown
snippet:
  Having established that the core quantity of information is the byte, the
  convention is to apply the
  [standard metric prefixes](Prefixes_for_units_of_electrical_measurement.md)
  to the byte to establish units:


title: arguments
href: zk/Passing_arguments_and_options_to_Bash_scripts.md
type: markdown
snippet:
  Here we test that the right number of
  [arguments](Passing_arguments_and_options_to_Bash_scripts.md)
  have been passed to the script:


title: electrical field
href: zk/Voltage.md#distinguishing-voltage-from-electric-field
type: markdown
snippet:
  In this configuration the same current flows through all the cells; it is not
  cumulative. We represent this as follow> However the voltage is cumulative: it
  is the _sum_ of the individual cell voltages, represented below as
  [electrical field](Voltage.md#distinguishing-voltage-from-electric-field):


title: remote tracking branch
href: zk/Remote_tracking_branches.md
type: markdown
snippet:
  You don't have to just cherry-pick locally, you can also cherry-pick from a
    [remote tracking branch](Remote_tracking_branches.md).


title: copying functions
href: zk/Functions_in_Python.md
type: markdown
snippet:
  The same principle that applies to
  [copying functions](Functions_in_Python.md)
  applies to copying objects created through classes: redeclaration results in a
  duplicate entity. Thus changes to the duplicate will affect the original.


title: kernal
href: zk/The_Kernel.md
type: markdown
snippet:
  Containers are native to the Linux [kernal](The_Kernel.md)
    and are key part of how it works. Thus when you run containers on Linux, you
    are using native capability. When you use containers on Windows or Mac you
    have to run a virtual version of Linux in order to exploit the capabilities of
    that kernel. (Docker provides this)


title: user space
href: zk/User_Space.md
type: markdown
snippet:
  In ordinary [user space](User_Space.md) applications share
  the _same_ processor, memory and file system resources. This increases the
  likelihood of resourcing challenges, dependency conflicts and security threats.
  Without modularisation and the titration of resources, you are opened up to much
  greater possibility of failure.


title: reciprocol
href: zk/Reciprocals.md
type: markdown
snippet:
  We combine the foregoing (that it is easier to divide by fractional amounts
  using multiplication) with the concept of a [reciprocol](Reciprocals.md) to
  arrive at a definitive method for dividing two fractions. It boils down to:
  _invert and multiply_:


title: REST API
href: zk/RESTful_APIs.md
type: markdown
snippet:
  The Docker Client is a thin API for making
    [REST API](RESTful_APIs.md) to the Docker Server. Any CLI
    command beginning `docker...` is an API request to the server.


title: electric current
href: zk/Current.md
type: markdown
snippet:
  Magnetism is a physical property produced by the _motion_ of electric charge,
  > which of course, is the same thing as
  > [electric current](Current.md)


title: shell session
href: zk/Shell-sessions-e6dd743dec1d4fe3b1ee672c8f9731f6
type: markdown
snippet:
  Every time a
    [shell session](Shell-sessions-e6dd743dec1d4fe3b1ee672c8f9731f6)
    spawns, a process takes place to gather and compile information that should be
    available to the shell process and its child processes. It obtains the data
    for these settings from a variety of different files and settings on the
    system.


title: shell session
href: zk/Shell-sessions-e6dd743dec1d4fe3b1ee672c8f9731f6
type: markdown
snippet:
  You can also add variables to config files that run on login such as your user
  `.bashrc` / `.zshrc` . This is obviously best for when you want the variables to
  persist and be accessible within every
  [shell session](Shell-sessions-e6dd743dec1d4fe3b1ee672c8f9731f6).


title: solution
href: zk/Algebra key terms.md#678811
type: markdown
snippet:
  Two equations are equivalent if they have the same
  > [solution](Algebra%20key%20terms.md#678811) set.


title: solution
href: zk/Algebra key terms.md#678811
type: markdown
snippet:
  $$ x - 4 = 3
  $$
  The [solution](Algebra%20key%20terms.md#678811) to this equation is $7$
  $$ x -
  4 (+4) = 3 (+ 4) $$


title: solution
href: zk/Algebra key terms.md#678811
type: markdown
snippet:
  $$ x + 4 = 9
  $$
  The [solution](Algebra%20key%20terms.md#678811) to this equation is $5$.
  $$ x +
  4 (-4) = 9(-4) $$


title: solution
href: zk/Algebra key terms.md#678811
type: markdown
snippet:
  $$x \cdot 2 = 10  $$
  The [solution](Algebra%20key%20terms.md#678811) to this equation is $5$.
  $$
  (x \cdot 2) \cdot 3 = 10 \cdot 3 $$ Here we have multiplied each side of the
  equation by $3$. If $x =5$ then


title: solution
href: zk/Algebra key terms.md#678811
type: markdown
snippet:
  $$x \cdot 3 = 18  $$
  The [solution](Algebra%20key%20terms.md#678811) to this equation is $6$.
  $$\frac{x
  \cdot 3}{3} = \frac{18}{3}
  $$
  Here we have divided each side of the equation by $3$. If $x$ is 6, then
  $$\frac{6
  \cdot 3}{3} = 6$$
  $$\frac{18}{3} = 6 $$


title: variables
href: zk/Variables_and_data_types.md
type: markdown
snippet:
  We use most frequently for returning the value of stored
  [variables](Variables_and_data_types.md).
  Techically we do not have to use the braces, we can retrieve with just `$var`
  however it's better to use them to minimise interpretation fuck-ups which happen
  a lot.


title: sub-shell
href: zk/Shell_sessions.md
type: markdown
snippet:
  Command substitution (circle-brackets) allows us to put the output of one
  command inside another. Bash runs the bracketed command in a
  [sub-shell](Shell_sessions.md) and then returns it
  to the main user shell.


title: equivalent
href: zk/Equivalent fractions.md
type: markdown
snippet:
  When we divide by the common divisor is acts as a divisor. When we multiply by
  the common divisor it acts as a factor. The fact that the fractions are
  [equivalent](Equivalent%20fractions.md) in both cases indicates that the
  properties are equivalent.


title: CPU Architecture
href: zk/CPU_architecture.md#arithmetic-logic-unit
type: markdown
snippet:
  Now the command will be executed. The operand is copied to the Memory Address
  Register and then passed to the Memory Data Register and the command is carried
  out by the ALU. The activities of ALU are covered in
  [CPU Architecture](CPU_architecture.md#arithmetic-logic-unit)
  and the notes on
  [Logic Gates](Logic_gates.md).


title: registers
href: zk/CPU_architecture.md#registers
type: markdown
snippet:
  If the instruction is iterative (e.g. adding two numbers and then multiplying
    by another number), the instruction will tell the CPU to store the interim
    first value in the CPU's
    [registers](CPU_architecture.md#registers). As
    these are part of the CPU, the data can be retrieved more readily. If the
    value is not expected to be used again immediately, it goes to the DRAM or
    harddisk.


title: redirect
href: zk/Redirection.md
type: markdown
snippet:
  They are typically used when you want to
  [redirect](Redirection.md) the output of the
  standard/input /output/error somewhere, e.g a file or as input to another
  program. A classic case is `[some_command] > /dev/null 2>&1`


title: $0
href: zk/Passing_arguments_and_options_to_Bash_scripts.md#passing-arguments
type: markdown
snippet:
  They are all technically "files" which are open and which append themselves to
  every process that can run in the shell. For any command or program that you
  run, you will be able to access `0`, `1` and `2` for them. In this way they are
  similar to variables like
  [`$0`](Passing_arguments_and_options_to_Bash_scripts.md#passing-arguments)
  and
  [`$@`](Passing_arguments_and_options_to_Bash_scripts.md#passing-arguments).
  They have a universal meaning within the context of the shell runtime.


title: database
href: zk/Basic_database_concepts.md
type: markdown
snippet:
  A filesytem is a form of [database](Basic_database_concepts.md); it
  > supplies the structure to transform a simple block device into the
  > sophisticated hierarchy of files and subdirectories that users can understand.


title: swap
href: zk/Swap_space.md
type: markdown
snippet:
  It shows my root and home filesystems and my
  [swap](Swap_space.md) file. Note that we use the UUID
  to name the partition rather than its name in `/dev/`. The order of the
  parameters is as follows:


title: passing arguments to scripts
href: zk/Passing_arguments_to_Bash_scripts.md
type: markdown
snippet:
  We can access all the arguments passed to a function using the `$@` syntax we
  encountered before when
  [passing arguments to scripts](Passing_arguments_to_Bash_scripts.md).
  (Here a function is a kind of script in miniature so the process is the same.)


title: equivalent
href: zk/Equivalent fractions.md
type: markdown
snippet:
  Let $a,b$ be any integers. The following three fractions are
  > [equivalent](Equivalent%20fractions.md):
  > $$\frac{-5}{15}, \frac{5}{-15}, - \frac{5}{15}$$


title: hardware simulator
href: zk/Hardware_simulation.md
type: markdown
snippet:
  The hardware designer specifies a chip's logic by writing an HDL program which
  is then rigorously tested. At this stage, a
  [hardware simulator](Hardware_simulation.md) takes the
  HDL program as input and creates a software representation of the chip logic.
  The designer can instruct the simulator to test the virtual chip on various sets
  of inputs. This is done to check the chip's functionality but also to benchmark
  a variety of other parameters such as speed of computation and energy
  consumption.


title: input and output pins
href: zk/Integrated_circuits.md
type: markdown
snippet:
  In an HDL program we distinguish internal pins along with the standard
  [input and output pins](Integrated_circuits.md).
  At the level of the interface, we are concerned only with input and output pins
  (in the example program these are `a`, `b` and `out`). It is at the level of the
  implementation that internal pins are encountered. In the example these are the
  connections between, e.g. the AND and NOT gates such as
  `And (a=a, b-notb, out=w1)`. This means the AND gate is receiving through its
  `a` pin the input `a` value and through its `b` pin the value of `b` inverted by
  a NOT. `out` is the value that is computed based on the input pins of `a` and
  `b`.


title: Boolean function
href: zk/Boolean_functions.md
type: markdown
snippet:
  Along with the HDL file we also create a test file. This runs the chip against
  the inputs we supply, these will typically be equivalent to the (left-hand)
  truth-values column in a truth table which is the same as the parameters passed
  to a [Boolean function](Boolean_functions.md), for
  example:


title: equivalent
href: zk/Equivalent fractions.md
type: markdown
snippet:
  Whenever we increase a fraction, the resultant fraction will always be
  > [equivalent](Equivalent%20fractions.md) to the fraction we started with.


title: sort
href: zk/Sorting_lists_in_Python.md
type: markdown
snippet:
  Assuming the sub-lists have an identical structure, you can
  [sort](Sorting_lists_in_Python.md) them by
  a common property by passing a
  [lambda function](Lambdas_in_Python.md) to
  the `key` value of `sorted()` and `.sort()`.


title: map
href: zk/Map_and_filter_in_Python.md
type: markdown
snippet:
  Below we use
  [map](Map_and_filter_in_Python.md) and a
  [lambda function](Lambdas_in_Python.md) to
  convert the first element of each iner list from a Unix timestamp to a readable
  string:


title: dictionary comprehension
href: zk/List_comprehension_etc.md#dictionary-comprehension
type: markdown
snippet:
  Accordingly, we create a dictionary which uses the unique key in each list as
  the key of each dictionary entry via
  [dictionary comprehension](List_comprehension_etc.md#dictionary-comprehension)
  that loops through each value in the inner lists of the multidimensional array.
  We then parse the values of the dictionary into a list.


title: REST APIs
href: zk/RESTful_APIs.md#rest
type: markdown
snippet:
  The best way to think of GraphQL architecturally is to think of it as a
  > different technique for instantiating the _uniform interface_, _client/server
  > decoupling_, and _layered-system architecture_ contraints of traditional
  > [REST APIs](RESTful_APIs.md#rest). However, instead of making
  > GET or POST requests to a REST endpoint URL and passing parameters, you send a
  > structured query object.


title: resistor
href: zk/Resistance.md#resistors
type: markdown
snippet:
  An LED diode lights up when the right amount of current flows through it. A
  standard LED has a maximum current of 20mA. An appropriate
  [resistor](Resistance.md#resistors)
  must therefore be added to the circuit to ensure the current doesn't exeedd this
  amount.


title: map, filter
href: zk/Map_and_filter_in_Python.md
type: markdown
snippet:
  They are most often used unnamed with the functional methods
  [map, filter](Map_and_filter_in_Python.md)
  and reduce.


title: NOR
href: zk/Logic_gates.md#nor-gate
type: markdown
snippet:
  The circuit diagram latch symbol obviously encapsulates more complex
  functionality that occurs at the sub-circuit level. We will demonstrate how this
  functionality can be achieved with two
  [NOR](Logic_gates.md#nor-gate) gates.


title: map and filter
href: zk/Map_and_filter_in_Python.md
type: markdown
snippet:
  Since its introduction to the language, the same functionality has become
  achievable by using functional methods like
  [`map` and `filter`](Map_and_filter_in_Python.md),
  utilising [lambdas](Lambdas_in_Python.md)
  however list comprehension is often more straightforward and easier to read.


title: test
href: zk/Test_values_in_Bash.md
type: markdown
snippet:
  Here we pass all the elements of the array to a
  [test](Test_values_in_Bash.md) condition which
  tests for an empty string.


title: function
href: zk/Functions_in_Bash.md
type: markdown
snippet:
  When you pass an array as an argument to a
  [function](Functions_in_Bash.md) it will not
  immediately be understood to be an array.


title: loop through each character in a string
href: zk/Strings_in_bash.md#loop-through-each-character-in-a-string
type: markdown
snippet:
  We are leveraging this aspect of Bash when we
  [loop through each character in a string](Strings_in_bash.md#loop-through-each-character-in-a-string).


title: pins
href: zk/Integrated_circuits.md
type: markdown
snippet:
  Logic gates are the basic building blocks of digital computing. **A logic gate
  is an electrical circuit that has one or more than one input and only one
  output.** The input and output points of the gate are
  [pins](Integrated_circuits.md) The
  input controls the output and the logic determining which types of input
  (on/off) lead to specific outputs (on/off) is isomorphic with the
  truth-conditions of the
  [Boolean connectives](Truth-functional_connectives.md) specifiable in
  terms of [truth tables](Truth-tables.md).


title: transistor
href: zk/Transistors.md
type: markdown
snippet:
  Physically, what 'travels through' the gates is electrical current and what
  constitutes the 'gate' is a
  [transistor](Transistors.md)
  responding to the current. Going up a level of abstraction, the current/ charge
  is identified with a
  [bit](Binary_units_of_measurement.md#binary-units-of-measurement).
  It is bits that go into the gate and bits which come out: binary information
  that may be either 1 or 0.


title: Adders
href: zk/Half_adder_and_full_adder.md
type: markdown
snippet:
  An example of a composite gate would be a three-way AND. An AND with three
  inputs rather than the standard two that furnish the elementary AND gate. This
  gate would output 1 when all three gates have the value 1 and 0 otherwise.
  [Adders](Half_adder_and_full_adder.md)
  and [latche>s](Latches.md) whilst
  being
  [integrated circuits](Integrated_circuits.md)
  are also, technically speaking, composite gates.


title: hardware abstraction
href: zk/Hardware_abstraction_and_modularity.md
type: markdown
snippet:
  Importantly, a single interface may be implemented in a variety of ways. There
  > is a one-to-many relationship at work here. From the point of view of the user
  > interface these differences should not be detectable. This is another example
  > of
  > [hardware abstraction](Hardware_abstraction_and_modularity.md)


title: CPU
href: CPU_architecture
type: wiki-link
snippet:
  No matter how a program was originally written, it eventually needs to execute
  on a [[CPU_architecture|CPU]] as a series of machine language instructions.


title: ARM ISA
href: Instruction_set_architectures
type: wiki-link
snippet:
  The following machine instruction is an instruction that would be understood by
  an [[Instruction_set_architectures| ARM ISA]]. It moves the number `4` into the
  `r7` register:


title: Hexadecimal_number_system
href: Hexadecimal_number_system
type: wiki-link
snippet:
  Binary sequences are hard to understand, even if converted to the
  [[Hexadecimal_number_system]]. We have a better way of managing operations on
  the machine level: [assembly](Assembly.md)


title: queue
href: zk/Queue.md
type: markdown
snippet:
  As the name indicates, its operating mode is that of a
  [queue](Queue.md) data structure offering first-in, first-out
  and other queue implementations.


title: add fractions with a common denominator
href: zk/Add_Subtract_Fractions.md#adding-subracting-fractions-with-common-denominators
type: markdown
snippet:
  But we know that when we
  [add fractions with a common denominator](Add_Subtract_Fractions.md#adding-subracting-fractions-with-common-denominators),
  we only add the numerators, not the denominators. Thus the calculation would
  actually be:


title: using factorization
href: zk/Multiplying_fractions.md#prime-factorisation-in-place
type: markdown
snippet:
  Then carry out the multiplication
     [using factorization](Multiplying_fractions.md#prime-factorisation-in-place):


title: invert and multiply
href: zk/Dividing_fractions.md#formal-specification-of-how-to-divide-fractions'
type: markdown
snippet:
  Again we convert the mixed fraction into an improper fraction and then follow
  the requisite rule, in the case of division this is to
  [invert and multiply](Dividing_fractions.md#formal-specification-of-how-to-divide-fractions').


title: reducing fractions
href: zk/Reducing_fractions.md
type: markdown
snippet:
  It would be laborious to reduce such a large product using factor trees or the
  repeated application of divisors, as defined in
  [reducing fractions](Reducing_fractions.md). We can use a more efficient
  method. This method can be applied at the point at which we conduct the
  multiplication rather than afterwards once we have the product. We express the
  the initial multiplicands as prime factors:


title: query constants
href: zk/Apollo_Client.md#query-constants
type: markdown
snippet:
  As with queries and
  [query constants](Apollo_Client.md#query-constants) we
  wrap our mutation in a `gql` template string:


title: type-guarding
href: zk/Type_guarding_and_narrowing.md
type: markdown
snippet:
  One way to get around it is to use better
  [type-guarding](Type_guarding_and_narrowing.md) and conditionality and to
  cover cases where the value may be undefined.


title: $PATH
href: zk/The_PATH.md
type: markdown
snippet:
  When we run a program like `cd` or `npm` we don’t have to type `./cd.sh` or
  `./npm.sh`. This is because a reference to the program file is already in our
  [`$PATH`](The_PATH.md).


title: AWS API Gateway
href: zk/AWS_API_Gateway.md
type: markdown
snippet:
  We will do this using [AWS API Gateway](AWS_API_Gateway.md). We
  select "Add trigger" from the dashboard view and input basic settings:


title: factors
href: zk/Factors and divisors.md
type: markdown
snippet:
  For any whole number $n$ where $n \neq 1$, $n$ is prime if and only if its
  > sole [factors](Factors%20and%20divisors.md) are $1$ and $n$


title: 8-bits long
href: zk/Binary_units_of_measurement.md
type: markdown
snippet:
  When Python runs in this implementation, code written in C converts it to
  bytecode (so-called because each instruction is
  [8-bits long](Binary_units_of_measurement.md)). This is a
  lower-level transliteration of Python is not meant to be understood by the CPU
  (since it is not binary) but rather to be run in the Python virtual machine
  which is equipped to understand bytecode. The Python Virtual Machine is
  therefore also known as "bytecode interpreter" or the CPython VM. The VM then
  converts bytecode into machine-executable code.


title: HTTP request types
href: zk/HTTP_request_types.md
type: markdown
snippet:
  A basic example of a REST API would be a series of methods corresponding to the
  main [HTTP request types](HTTP_request_types.md).


title: split the contents into an array
href: zk/Split_into_array.md
type: markdown
snippet:
  `read` will parse line by line using a space (`\n`) as the default delimiter.
  You can use IFS to parse by other characters and/or
  [split the contents into an array](Split_into_array.md).


title: find
href: zk/Find.md
type: markdown
snippet:
  Here we use [find](Find.md) to collate the files in
  the current directory and then pipe them to read.


title: cherry-picking
href: zk/Cherry_picking_a_branch.md
type: markdown
snippet:
  The main difference between the two approaches is that
  [cherry-picking](Cherry_picking_a_branch.md) is a more selective
  process, where you can pick and choose specific commits that you want to include
  in another branch. This can be useful when you only want to apply specific
  changes or fixes from one branch to another, without including all the changes
  made in the original branch.


title: file descriptors
href: zk/File_descriptors_and_redirection.md
type: markdown
snippet:
  The `2>&1` argument is the content: any errors that the program may generate and
  try to show in stout. Notice we are using the
  [file descriptors](File_descriptors_and_redirection.md)
  `1` and `2`.


title: file descriptors
href: zk/File_descriptors.md
type: markdown
snippet:
  It is common practice to combine redirection with the
  [file descriptors](File_descriptors.md) to redirect
  the output of `stdout` and `stderr`. A common case is to
  [redirect error output to `/dev/null`](Redirect_to_dev_null.md).


title: greatest common divisor
href: zk/Factors and divisors.md#greatest-common-divisor
type: markdown
snippet:
  A fraction is said to be _reduced to its lowest terms_ if the
  > [greatest common divisor](Factors%20and%20divisors.md#greatest-common-divisor)
  > of the numerator and the denominator is $1$.


title: equivalent
href: zk/Equivalent fractions.md
type: markdown
snippet:
  Whenever we reduce a fraction, the resultant fraction will always be
  > [equivalent](Equivalent%20fractions.md) to the fraction we started with.


title: highest common divisor
href: zk/Factors and divisors.md#greatest-common-divisor
type: markdown
snippet:
  In the previous example the reduction took two steps: first we divided by two
  and then we divided by three. There is a more efficient way: find the
  [highest common divisor](Factors%20and%20divisors.md#greatest-common-divisor) of
  the numerator and denominator and then use this as the basis for the reduction.
  With this method, the reduction can be completed in a single step.


title: factors
href: zk/Factors and divisors.md#factors
type: markdown
snippet:
  Note how our earlier two divisors 2 and 3 are
  [factors](Factors%20and%20divisors.md#factors) of 6, showing the consistency
  between the two methods.


title: interchangeability of factors and divisors
href: zk/Factors and divisors.md
type: markdown
snippet:
  The two methods above are not very systematic and are quite heuristic. The third
  approach is more systematic and relies on the
  [interchangeability of factors and divisors](Factors%20and%20divisors.md).


title: factor
href: zk/Factors and divisors.md#factors
type: markdown
snippet:
  Instead of thinking asking what is the greatest common divisor of 18 and 24 we
  could ask: which single number can we multiply by to get 18 and 24? Obviously
  both numbers are in the six times table. This is therefore to say that 6 is a
  [factor](Factors%20and%20divisors.md#factors) of both: we can multiply some
  number by 6 to arrive at both 18 and 24. The numbers are 3 and 4 respectively:


title: prime factorization
href: zk/Prime factorization.md
type: markdown
snippet:
  A better method is to utilise [prime factorization](Prime%20factorization.md)
  combined with the canceling technique.


title: fraction with unlike terms
href: zk/Handling negative fractions.md#fractions-with-unlike-terms
type: markdown
snippet:
  This fraction is an instance of a
    [fraction with unlike terms](Handling%20negative%20fractions.md#fractions-with-unlike-terms).


title: fraction with like terms
href: zk/Handling negative fractions.md#fractions-with-like-terms
type: markdown
snippet:
  This fraction is an instance of a
    [fraction with like terms](Handling%20negative%20fractions.md#fractions-with-like-terms).


title: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html
href: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html
type: markdown
snippet:
  See
  [https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html)


title: IAM user
href: zk/zk/AWS_User_management_and_roles.md#iam
type: markdown
snippet:
  You require an access key for the given
  [IAM user](zk/AWS_User_management_and_roles.md#iam). You should create an IAM
  account specific to the project with bounded permissions.


title: IAM
href: zk/zk/AWS_User_management_and_roles.md#iam
type: markdown
snippet:
  This information can be found in the Security Credentials section of the given
  [IAM](zk/AWS_User_management_and_roles.md#iam) user:


title: handler function
href: zk/Lambda_handler_function.md
type: markdown
snippet:
  This details the location of the [handler function](/Lambda_handler_function.md)
  which is contained at the path `hello-world/app.js`:


title: S3
href: zk/zk/AWS_S3.md
type: markdown
snippet:
  The packaging proces will first archive all of the project artefacts into a zip
  file and then upload that to [S3](zk/AWS_S3.md). A reference to this S3 entity
  is then provided to CloudFormation.


title: environmental and shell variables
href: zk/Environmental-and-shell-variables-04d5ec7e8e2b486a93f002bf686e4bbb
type: markdown
snippet:
  The type of shell session that you are currently in affects the
  [environmental and shell variables](Environmental-and-shell-variables-04d5ec7e8e2b486a93f002bf686e4bbb)
  that you can access. This is because the order in which configuration files are
  read on initialisation differs depending on the type of shell.


title: Lambda
href: zk/Lambda_programming_model.md
type: markdown
snippet:
  At the beginning you define a `StartAt` state which is the entrypoint of the
  state machine. This can be manually triggered, or more likely, triggered by
  another AWS service such as a
  [Lambda](Lambda_programming_model.md), an
  [API Gateway](AWS_API_Gateway.md) request or a messaging/queue
  event.


title: list
href: zk/Lists_in_Python.md
type: markdown
snippet:
  The `split()` function in Python is used to divide a string into multiple parts
  at the occurrence of a given separator. This function returns a
  [list](Lists_in_Python.md) of substrings.


title: kernel
href: zk/The_Kernel.md
type: markdown
snippet:
  To use an existing disk partition as a swap you can run the command
  `mkswap [device]` and then `swapon [device]` to register the space with the
  [kernel](The_Kernel.md).


title: fstab
href: zk/Filesystems.md#fstab
type: markdown
snippet:
  You will want the swap to be activated every time the OS boots so add the
  following line to the [fstab](Filesystems.md#fstab),
  where `/sda3` is used as the example partition:


title: array
href: zk/Lists_and_arrays.md
type: markdown
snippet:
  Note: this syntax can also be used to test if a given element exists in an
  > [array](Lists_and_arrays.md).


title: pip
href: zk/Python_package_management.md
type: markdown
snippet:
  Pytest is the most popular testing library for Python. It is not included with
  the Python standard library so it must be installed with
  [pip](Python_package_management.md).
  While it does not include a declaration library, it is robust enough to handle
  most scenarios having a rich and expressive set of constructs and decorators
  that let you declare what your tests should do, under what conditions they
  should run, and how they should interact with the rest of your system.


title: memory management unit
href: zk/Virtual_memory_and_the_MMU.md#the-memory-management-unit-mmu
type: markdown
snippet:
  Modern CPUs include a
  > [memory management unit](Virtual_memory_and_the_MMU.md#the-memory-management-unit-mmu)
  > which provides the kernel with **virtual** memory. In this scenario, memory
  > isn't directly accessed by the process instead it works on the assumption that
  > is has access to the entire memory of the machine and this is then translated
  > into a map that is applied to the real memory and managed by the kernel.


title: clock pulses
href: zk/Clock_signals.md
type: markdown
snippet:
  The circuit will have three memory components, each representing one bit of the
  3-bit number. When the
  [clock pulses](Clock_signals.md), the
  3-bit number increments by one. We need to synchronise the operation with a
  clock because each bit by itself is meaningless, it only gains meaning by the
  relation it sustains to the other two bits hence it must be kept in sync with
  them.


title: T flip-flop
href: zk/Flip_flops.md#t-flip-flops
type: markdown
snippet:
  This means that to construct a circuit that displays this behaviour we just have
  to use a
  [T flip-flop](Flip_flops.md#t-flip-flops)
  since the only state change we need is a single bit toggle three times that
  retains its value.


title: voltage
href: zk/Voltage.md
type: markdown
snippet:
  Thus instead of switches, modern digital circuits use transistors, a special
  electrical component that controls the flow of current in the manner of a switch
  where the 'off' and 'on' states are represented by
  [voltage](Voltage.md) values within
  set parameters.


title: AND
href: zk/Logic_gates.md#and-gate
type: markdown
snippet:
  For example to create an
  [AND](Logic_gates.md#and-gate) gate
  we would have two voltage inputs going into two transistors that are connected
  in sequence. The two transistors create a continuous line going from the
  collector of one to the emitter of the other. If either voltage input is low
  then the voltage of the combined line is low (equivalent to the circuit being
  broken) and there is no current flowing.


title: OR
href: zk/Logic_gates.md#or-gate
type: markdown
snippet:
  Below, an
  [OR](Logic_gates.md#or-gate) has been
  constructed with transistors. If a voltage is applied to the base of either
  transistor, the current reaches the V-out terminal.


title: immediate sentential components
href: zk/Syntax of sentential logic.md
type: markdown
snippet:
  The core truth-tables tell us how to determine the truth-value of a molecular
  > sentence given the truth-values of its
  > [immediate sentential components](Syntax%20of%20sentential%20logic.md). And if
  > the immediate sentential components of a molecular sentence are also
  > molecular, we can use the information in the characteristic truth-tables to
  > determine how the truth-value of each immediate component depends n the
  > truth-values of _its_ components and so on.


title: consistent
href: zk/Consistency.md
type: markdown
snippet:
  Recall that a set of propositions is logically or truth-functionally
  [consistent](Consistency.md) just if there is at least one assignment of truth
  conditions which results in all members of the set being true. To identify
  consistency for a set of three propositions via the truth table approach we
  would need to construct a truth table with $2^3$ (8) rows. Assume that this set
  is consistent on one partial assignment only. This means that 87.5% of our rows
  are redundant, they are not required to prove the consistency of the set.
  However we can only know this and we can only be sure of consistency once we
  have gone through the process of generating an assignment for each row.


title: logical falsity
href: zk/Logical truth and falsity.md#logical-falsity
type: markdown
snippet:
  When we wish to assess
  [logical falsity](Logical%20truth%20and%20falsity.md#logical-falsity) we are not
  focused on sets however, we are interested in a property of a sentence. However
  we can easily construe single sentences as unit sets: sets with a single member.
  With this in mind and the above accounts of consistency and logical falsity we
  are equipped to express logical falsity in terms of truth-trees with the
  following rule:


title: logically true
href: zk/Logical truth and falsity.md#logical-truth
type: markdown
snippet:
  For a sentence $P$ to be
  [logically true](Logical%20truth%20and%20falsity.md#logical-truth), there must
  be no possible assignment in which $P$ is false. We express this informally by
  saying _it is not possible to consistently deny $P$._ We know that in terms of
  truth trees an inconsistent set is a closed tree therefore a unit set of ${ P }$
  is logically true if ${ \sim P }$ is a closed tree. This is to say: if the
  negation of $P$ is inconsistent.


title: Indeterminacy
href: zk/Indeterminacy.md
type: markdown
snippet:
  [Indeterminacy](Indeterminacy.md) follows from the two definitions above; we do
  not require any additional apparatus. We recall that a sentence $P$ is logically
  indeterminate just if it is neither logically true or logically false. Thus the
  truth tree for an indeterminate sentence is straightforward:


title: logically equivalent
href: zk/Logical equivalence.md
type: markdown
snippet:
  Recall that $P$ and $Q$ are [logically equivalent](Logical%20equivalence.md)
  just if there is no truth assignment on which one is true and the other is
  false. We know from the
  [material biconditional shorthand](Corresponding%20material%20and%20biconditional.md#corresponding-material-biconditional)
  that this state of affairs can be expressed as $P \equiv Q$ and that if this
  compound sentence is true on every assignment then both simple sentences are
  equivalent. But ‘true on every assignment’ is another way of saying _logically
  true_ since there is no possibility of a false assignment. We already know what
  logical truth looks like as a truth tree: it is a closed tree for the negation
  of the sentence being tested. Therefore, to test the logical equivalence of two
  sentences it is necessary to construct a truth tree for the negation of the
  sentences conjoined by the biconditional (i.e. $\sim (P \equiv Q)$ )and see if
  this results in a closed tree. If it does, the two sentences are logically
  equivalent.


title: entailment
href: zk/Validity and entailment.md#entailment
type: markdown
snippet:
  Let’s remind ourselves of the meaning of truth-functional
  [entailment](Validity%20and%20entailment.md#entailment) and
  [validity](Validity%20and%20entailment.md#validity) and the relation between the
  two. $\Gamma$ $\vdash$ $P$ is true if and only if there is no truth-assignment
  in which every member of $\Gamma$ is true and $P$ is false. Entailment is
  closely related to validity; it is really just a matter of emphasis: we say that
  $\Gamma$ are the premises and $P$ is the conclusion and that this is a valid
  argument if there is no assignment in which every member of $\Gamma$ is true and
  $P$ is false.


title: middlewear
href: zk/Middleware.md
type: markdown
snippet:
  Next we introduce GraphQL as a piece of Node.js
  [middlewear](Middleware.md), with the
  `app.use()` method.


title: original schema
href: zk/Apollo_Server.md#example-schema
type: markdown
snippet:
  In order to demonstrate arguments we need to expand the
  [original schema](Apollo_Server.md#example-schema).


title: server-side process
href: zk/Apollo_Server.md
type: markdown
snippet:
  Now we have to create a resolver for our new `track` query. We will quickly run
  through the [server-side process](Apollo_Server.md).


title: useQuery hook
href: zk/Apollo_Client.md#usequery-hook
type: markdown
snippet:
  We can now write a proper query using the
  [useQuery hook](Apollo_Client.md#usequery-hook) from
  Apollo Client, with variables.


title: simple example
href: zk/Apollo_Client.md#query-constants
type: markdown
snippet:
  Note that in contrast to the
  [simple example](Apollo_Client.md#query-constants)
  because we are using variables, we have to pass-in an additional options object
  with the query constant that specifies our variables.


title: Virtual memory
href: zk/9_VirtualMemory.html#:~:text=Virtual memory also allows the,to more than one process
type: markdown
snippet:
  [Virtual memory](9_VirtualMemory.html#:~:text=Virtual%20memory%20also%20allows%20the,to%20more%20than%20one%20process)


title: partitions
href: zk/Partitions.md
type: markdown
snippet:
  A disk is divided up into [partitions](Partitions.md)
    which are subsections of the overall disk. The kernel presents each partition
    as a [block device](Devices.md) as it would with an entire
    disk.


title: user space
href: zk/User_Space.md
type: markdown
snippet:
  The **filesystem** is a database of files and directories: this comprises the
    bulk of the partition and is what you interact with in
    [user space](User_Space.md) when reading and writing data.


title: multiplicands
href: zk/Symbols-and-formal-conventions-80aeaf1872f94a0d97a2e8d07e3855bd
type: markdown
snippet:
  When **multiplying** whole numbers the placement of the
  [multiplicands](Symbols-and-formal-conventions-80aeaf1872f94a0d97a2e8d07e3855bd)
  does not affect the
  [product](Symbols-and-formal-conventions-80aeaf1872f94a0d97a2e8d07e3855bd).


title: expansion
href: zk/Expansions_and_substitutions.md
type: markdown
snippet:
  Note: we do not use a dollar-sign when referring to variables within
  > arithmetic evaluation, there is no need. If we do, we get an error. This is
  > because we are using an
  > [expansion](Expansions_and_substitutions.md),
  > therefore the variables are already being interpreted as variables.


title: printing-values-in-c
href: zk/printing-values-in-c.md
type: markdown
snippet:
  Format specifiers define the type of data to be printed on standard output. You
  need to use format specifiers whenever you are
  [printing-values-in-c](printing-values-in-c.md).


title: format specifier
href: zk/zk/format-specifiers-in-c.md
type: markdown
snippet:
  The `%d` is an example of a [format specifier](./zk/format-specifiers-in-c.md).
  It is the decimal integer format specifier.


title: zk/Elastic_Compute_Cloud
href: zk/Elastic_Compute_Cloud
type: wiki-link
snippet:
  AWS VPC is used to create a virtual network. This is typically used in concert
  with [[zk/Elastic_Compute_Cloud]] to manage connections to a virtual server both
  privately and accross the internet.


title: Arithmetic_Logic_Unit
href: Arithmetic_Logic_Unit
type: wiki-link
snippet:
  A family of CPUs that implement the core instructions of the
    [[Arithmetic_Logic_Unit]] in the same way share an ISA. Any software built for
    that ISA will work on any CPU that implements the ISA


title: word-size
href: zk/Signed_and_unsigned_numbers.md
type: markdown
snippet:
  There have been different, successive generations of x86 corresponding to
    their [word-size](Signed_and_unsigned_numbers.md): 16-bit, 32-bit, 64-bit.
    Word size here just means how many bits the processor can work with at a time.
    A 34-bit processor can operate on values that are 32 bits in length. This
    means it has 32bit [[CPU_architecture#registers|registers]], a 32-bit data
    [[Bus|bus]], a 32-bit address bus and so on.


title: logic gates
href: zk/Logic_gates.md
type: markdown
snippet:
  The half adder and full adder are components of digital circuits that enable us
  to carry out binary addition. Using adders and half adders we can add two binary
  numbers together. Adders are a type of [integrated circuit]() comprising certain
  [logic gates](Logic_gates.md) where the arrangement allows for the
  representation of the addition of bits.


title: XOR
href: zk/Logic_gates.md#xor-gate
type: markdown
snippet:
  We can see that the sum bit column replicates the truth-conditions of
  [XOR](Logic_gates.md#xor-gate):


title: heap memory
href: Heap_memory
type: wiki-link
snippet:
  Along with [[Heap_memory|heap memory]] heap memory, programs make use of
    _stack memory_ during runtime.


title: stack data structure
href: Stacks
type: wiki-link
snippet:
  Similarly to the [[Stacks|stack data structure]], it works on the basis of LIFO:
  the last item put on the stack is the first item to be withdrawn.


title: register
href: CPU_architecture#registers
type: wiki-link
snippet:
  A **stack pointer** is used to manage the items in the stack. This value is
  stored in a [[CPU_architecture#registers|register]] and its value is the memory
  address of the item currently on the top of the stack. Note: _not_ the value
  itself, the _address_ of the value.


title: memory leaks
href: Memory_leaks
type: wiki-link
snippet:
  Local variable storage: storing the variables local to a function's scope and
     removing them once the function returns, avoiding
     [[Memory_leaks|memory leaks]]


title: Memory_leaks
href: Memory_leaks
type: wiki-link
snippet:
  Whereas stack memory with it's LIFO structure has memory management built-in
  when programs allocate memory from the heap they must manually deallocate it
  when it is no longer required. This process of "freeing memory" is known as
  _garbage collection_. In a language like C, this is the explicit concern of the
  programmer and is not abstracted away. Failure to properly manage garbage
  collection is what causes [[Memory_leaks]].


title: ways around this
href: https://thom4.net/2014/self-contained-node-scripts/
type: markdown
snippet:
  If you use any module not in the Node core, you will need to have this installed
  globally for it to work. (There are
  [ways around this](https://thom4.net/2014/self-contained-node-scripts/) for Node
  scripts you publish but for personal scripts this doesn't matter.)


title: superuser
href: zk/User_Space.md#root-user-superuser
type: markdown
snippet:
  This is the domain of the [superuser](User_Space.md#root-user-superuser). The
    part of the filesystem that you need sudo priveleges to access and where you
    manage users


title: kernel
href: zk/The_Kernel.md
type: markdown
snippet:
  Most standard partition tables allow for primary, extended and logical
  partitions. The primary partition is the part of the harddisk that contains the
  operating system and is thus described as 'bootable' and may be called the 'boot
  partition'. During the bootstrapping process this is injected into memory as the
  [kernel](The_Kernel.md).


title: difference of potential
href: zk/Voltage.md
type: markdown
snippet:
  When there is an excess of electrons at one terminal (i.e. negatively charged
  atoms) and a deficiency of electrons at the other terminal (i.e. positively
  charged atoms), a [_difference of potential_](Voltage.md) exists between the two
  terminals.


title: current
href: zk/Current.md
type: markdown
snippet:
  We noted in the discussion of [current](Current.md) that current flows when
  there is a difference of potential between two points with negatively charged
  atoms at one point and positively charged atoms at the other.


title: form of energy
href: zk/Voltage_sources.md
type: markdown
snippet:
  Voltage is the application of this energy. Any
  [form of energy](Voltage_sources.md) that dislodges electrons from atoms can be
  used to produce current. Thus:


title: battery
href: zk/Cells_and_batteries.md
type: markdown
snippet:
  Given that voltage is the force that generates current, it would be natural to
  think that voltage only exists when a voltage source (such as a
  [battery](Cells_and_batteries.md)) is connected to a circuit. This however is
  not the case. Even if a 9V battery isn't connected to anything it still has a
  difference of potential of 9-volts accross its terminals. Remember voltage is
  _potential energy_ not just the actualisation of that energy.


title: Ohm's Law
href: zk/Ohms_Law.md
type: markdown
snippet:
  We can work out the voltage of the remaining voltage points by inverting
  [Ohm's Law](Ohms_Law.md): $V = I \times R$:


title: amp
href: zk/Current.md#formal-expression
type: markdown
snippet:
  One ohm is the resistance of a circuit or circuit element that permits a
  > steady current flow of one [amp](Current.md#formal-expression) (one
  > coulomb/second) when one [volt](Voltage.md#voltage) is applied to the circuit.


title: batteries
href: zk/Cells_and_batteries.md
type: markdown
snippet:
  The chemical creation of current is the physics behind
  [batteries](Cells_and_batteries.md). Chemical current production produces
  currents on a smaller and less industrial scale than generators.


title: exception
href: zk/Error_handling_in_Python.md
type: markdown
snippet:
  Obviously file access can raise errors - typically when the file you want to
  access does not exist (i.e. a `FileNotFoundError`
  [exception](Error_handling_in_Python.md)). We can manage this scenario with
  [exception handlers](Error_handling_in_Python.md):


title: HTTP request types
href: zk/HTTP_request_types.md
type: markdown
snippet:
  Express provides us with methods corresponding to each of the
  [HTTP request types](HTTP_request_types.md):


title: MongoDB database
href: zk/05_ Integrating_the_database.md
type: markdown
snippet:
  Typically when you create a RESTful API you are going to be returning data
  > from a database. For simplicity we are just going simulate this with a simple
  > data array so that we can focus on the Express syntax rather than database
  > handling. Later we will integrate this with a
  > [MongoDB database](05_%20Integrating_the_database.md).


title: middleware
href: zk/Middleware.md
type: markdown
snippet:
  We first create an instance of Express within `index.js`. This will be the main
  coordinating file and we will aim to minimise the amount of business logic we
  have in this file. It should really just be for initialization and managing
  [middleware](Middleware.md).


title: event emitter
href: zk/Events module.md#event-emitters
type: markdown
snippet:
  We create an [event emitter](Events%20module.md#event-emitters) and listener
  that listens for GET requests on a specified port and sends data in response to
  requests.


title: Joi validator
href: zk/Validation.md
type: markdown
snippet:
  We should accept alterations to the database that are not first validated. We
  can use the
  [Joi validator](Validation.md) to vet
  the request:


title: my notes
href: zk/Connect_to_Mongo_database.md
type: markdown
snippet:
  We will follow the routine for establishing a MongoDB instance as detailed in
  [my notes](Connect_to_Mongo_database.md) on Mongo:


title: Querying a collection
href: zk/Querying_a_Mongo_collection.md
type: markdown
snippet:
  Now we need to rewrite our RESTful request handlers so that the data is sourced
  from and added to the database. We will mainly be using the Mongo syntax defined
  at [Querying a collection](Querying_a_Mongo_collection.md) and
  [Adding documents to a collection](Adding_documents_to_a_Mongo_collection.md).
  We will also keep API validation within the `/model/` file.


title: query-first
href: zk/Update_a_Mongo_document.md#query-first-document-update
type: markdown
snippet:
  When updating a value in the database we are going to use the
  [query-first](Update_a_Mongo_document.md#query-first-document-update)
  approach to updating a Mongo document.


title: React_useReducer
href: zk/React_useReducer.md#refining-the-syntax
type: markdown
snippet:
  Now we need a reducer that will handle the state updates. We will just use the
  same setup as we used in the example of
  [React_useReducer](React_useReducer.md#refining-the-syntax):


title: https://www.geeksforgeeks.org/user-mode-and-kernel-mode-switching/
href: https://www.geeksforgeeks.org/user-mode-and-kernel-mode-switching/
type: implicit
snippet:
  !! Add info on kernel mode and user mode
  https://www.geeksforgeeks.org/user-mode-and-kernel-mode-switching/


title: Commutative Law
href: zk/Whole_numbers.md#the-commutative-property
type: markdown
snippet:
  Compare the
  [Commutative Law](Whole_numbers.md#the-commutative-property)
  in the context of arithmetic.


title: Associative Law
href: zk/Whole_numbers.md#the-associative-property
type: markdown
snippet:
  Compare the
  [Associative Law](Whole_numbers.md#the-associative-property)
  in the context of arithmetic.


title: Distributive Law applies in the case of algebra based on arithmetic
href: zk/Distributivity.md
type: markdown
snippet:
  Compare how the
  [Distributive Law applies in the case of algebra based on arithmetic](Distributivity.md):


title: DeMorgan's Laws
href: zk/DeMorgan's_Laws.md
type: markdown
snippet:
  In addition we have
  [DeMorgan's Laws](DeMorgan's_Laws.md) which express
  the relationship that obtains between the negations of conjunctive and
  disjunctive expressions:


title: logic gates
href: zk/Logic_gates.md
type: markdown
snippet:
  The fact that we can take a complex Boolean function and reduce it to a simpler
  formulation has great significance for the development of computer
  architectures, specifically
  [logic gates](Logic_gates.md). It
  would be rather resource intensive and inefficient to create a gate that is
  representative of the complex function. Whereas the simplified version only
  requires a single
  [OR gate](Logic_gates.md#or-gate).


title: logic circuits
href: zk/Digital_circuits.md
type: markdown
snippet:
  This is an important skill that we will use when constructing
  [logic circuits](Digital_circuits.md).
  We will go from truth conditions (i.e. what we want the circuit to do and when
  we want it to do it) to a function expression which is then reduced to its
  simplest form and implemented with
  [logic gates](Logic_gates.md).
  Specifically, NAND gates.


title: idempotence
href: zk/Boolean_algebra.md#idempotent-law
type: markdown
snippet:
  Notice that $\lnot(z)$ is repeated so we can remove the repetition through
  [idempotence](Boolean_algebra.md#idempotent-law):


title: NAND gate
href: zk/Logic_gates.md#nand-gate
type: markdown
snippet:
  Finally, we can simplify even further by doing away with AND and NOT and using a
  single
  [NAND gate](Logic_gates.md#nand-gate)
  which embodies the logic of both, being true in all instances where AND would be
  false: $\lnot (x \land  y)$.


title: trkjuth table
href: zk/Truth-tables.md
type: markdown
snippet:
  We can compute all possible outputs of the function by constructing a
  [trkjuth table](Truth-tables.md) with each possible
  variable as the truth conditions and the output of the function as the truth
  value:


title: process id
href: zk/Processes.md#processes-ps
type: markdown
snippet:
  The kernel starts a program called **init**. It has a
     [process id](Processes.md#processes-ps)
     of 1. This is the point at which [user space](User_Space.md) starts.


title: memory
href: zk/Memory.md
type: markdown
snippet:
  | Bus type      | Description                                                                                                                                                                                                        |
  | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
  | System bus    | The primary pathway between the CPU and [memory](Memory.md). It comprises the **data bus** that transfers data from the memory to the CPU and the **address bus** which transmits requests from the CPU to memory. |
  | Internal bus  | Connects local devices for example the harddisk to the CPU.                                                                                                                                                        |
  | External bus  | Connects peripheral devices such as disks and printers to the [motherboard](Motherboard.md)                                                                                                                        |
  | Expansion bus | Allows expansion boards to access the CPU and memory.                                                                                                                                                              |
  | Frontside bus | Main computer bus that determines data transfer rate speed and is the primary data transfer path between the CPU, RAM and other [motherboard](Motherboard.md) devices.                                             |
  | Backside bus  | Transfers secondary cache (L2 cache) data at faster speeds, allowing more efficient CPU operations                                                                                                                 |


title: capacitors
href: zk/Memory.md
type: markdown
snippet:
  This is the part of the CPU that stores data. The memory cells that comprise it
  do not have [capacitors](Memory.md) (unlike RAM)
  so they cannot store very much data but they work faster, which is what is
  important. Because their memory capacity is so small, we measure the size of
  registers in bits rather than bytes.


title: memory hierarchy
href: zk/Memory.md#the-memory-hierarchy
type: markdown
snippet:
  In terms of speed, registers sit at the top part of the overall
  [memory hierarchy](Memory.md#the-memory-hierarchy).


title: controller
href: zk/Chipset_and_controllers.md
type: markdown
snippet:
  The CPU's [controller](Chipset_and_controllers.md). It
  takes the instructions in binary form from RAM memory (separate from the CPU,
  but connected) and then signals to the to ALU and memory registers what it is
  supposed to do to execute the instructions. Think of it as the overseer that
  gets the ALU and registers to work together to run program instructions.


title: logic gates
href: zk/Logic_gates.md
type: markdown
snippet:
  The clock's circuitry is based on a quartz crystal system like that used in
  watches. At precisely timed intervals, the clock sends out pulses of electricity
  that cause bits to move from place to place within
  [logic gates](Logic_gates.md) or
  between logic gates and
  [registers](CPU_architecture.md#registers). This is
  covered in greater detail in the discussion of
  [clock signals in digital circuits](Clock_signals.md).


title: kernel
href: zk/The_Kernel.md
type: markdown
snippet:
  Each "cycle" is the execution of a process that commences once the
  [kernel](The_Kernel.md) hands control to the CPU. Each cycle
  follows a sequence of events known as
  [fetch, decode, and execute](Fetch_decode_execute.md).


title: electromagentic waves
href: zk/Electromagnetism.md
type: markdown
snippet:
  Hertz was the scientist who detected
  [electromagentic waves](Electromagnetism.md).
  We use Hertz as a measure of the frequency of electromatic wave cycles in a
  signal.


title: motherboard
href: zk/Motherboard.md
type: markdown
snippet:
  The chipset manages the data flow between the different components that comprise
  the [motherboard](Motherboard.md): processor,
  [memory](Memory.md),
  [harddisk](What_are_disks.md) and peripherals.


title: system bus
href: zk/Bus.md
type: markdown
snippet:
  Buses run in and out of the chipset into these key motherboard components. The
  main chipset is a kind of junction that sits between the memory and CPU through
  which the [system bus](Bus.md) passes.


title: battery
href: zk/Cells_and_batteries.md#cells-and-batteries
type: markdown
snippet:
  Below is a basic circuit representing a 9-volt
  [battery](Cells_and_batteries.md#cells-and-batteries)
  with a 10,000$\Omega$
  [resistor](Resistance.md) attached
  accross its terminals. Through the application of
  [Ohm's Law](Ohms_Law.md) we can
  determine that the maximum current will be 0.9 miliamps.


title: duck typing
href: zk/Custom_types_in_TypeScript.md#duck-typing
type: markdown
snippet:
  You shouldn't confuse `implements` with `extends`. `implements` just checks the
  class as an interface in accordance with the principles of
  [duck typing](Custom_types_in_TypeScript.md#duck-typing):
  i.e the implementing class should have the same properties and methods. It
  doesn't affect anything internal to the methods or properties. So e.g, if you
  typed a method parameter as `string` in the base class, this would still default
  to `any` in the derived class.


title: electromagnetic
href: zk/Electromagnetism.md
type: markdown
snippet:
  A single iteration of the volatage rising and falling is a **pulse**. A complete
  oscillation from low to high and back to low is a **cycle**. As with all
  [electromagnetic](Electromagnetism.md)
  signals we measure the frequency of the wave in Hertz: cylcles per second. We
  also further distinguish the rising and falling edge of a pulse. Rising
  represents the signal passing from ground to its maximum voltage and falling is
  the reverse (the electrons moving from the voltage source to ground).


title: CPU
href: zk/CPU_architecture.md#the-system-clock
type: markdown
snippet:
  The role of the clock is essential in the functioning of the
  [CPU](CPU_architecture.md#the-system-clock). It is
  the system clock that gives CPUs their performance rating: how many processes
  can execute within a given clock cycle.


title: principle of the immutability of elements
href: zk/Elements-992594b9cd2e483c85cddddffeb16f11
type: markdown
snippet:
  We change components by using state, not by mutating props. This is consistent
  with React's
  [principle of the immutability of elements](Elements-992594b9cd2e483c85cddddffeb16f11).


title: data type
href: zk/Data_types_in_MySQL.md
type: markdown
snippet:
  Below is an example of this in practice. Each field corresponds to a column. We
  specify the name of the field and its corresponding
  [data type](Data_types_in_MySQL.md). Every table must have a
  **primary key**. In the example, `employee_id` is the primary key.


title: collections and documents
href: zk/MongoDB_Introduction.md
type: markdown
snippet:
  In order start adding
  [collections and documents](MongoDB_Introduction.md) to our database,
  we use Mongoose's **schema** structure. (This is specific to Mongoose and is not
  a structure that is a part of Mongo in general.)


title: separate entry
href: zk/Validating_Mongoose_schemas.md
type: markdown
snippet:
  Note that we set our validation criteria as the second property for each
  > schema value. There is more info info on validation in a
  > [separate entry](Validating_Mongoose_schemas.md);


title: mode
href: zk/File_permissions_and_execution.md#what-the-output-means
type: markdown
snippet:
  The
  [mode](File_permissions_and_execution.md#what-the-output-means)
  is different from ordinary files. Each device file is prepended with
  `b, p, c, s` before the standard permissions. These stand for the major types of
  devices: _block, character, pipe_ and _socket_.


title: bash scripting
href: zk/Redirect_to_dev_null.md
type: markdown
snippet:
  `/dev/null` is a virtual device: it doesn't actually exist as a piece of
  hardware on the system. It can be useful when
  [bash scripting](Redirect_to_dev_null.md) as a
  place to direct output that you don't care about, for example errors or verbose
  program read-outs.


title: logic gates
href: zk/Logic_gates.md
type: markdown
snippet:
  In a standard electrical circuit, voltage, current and resistance can vary over
  a wide range of values however in the binary context we want to deal with
  discrete values (zeros and ones) which can be fed into the various
  [logic gates](Logic_gates.md).


title: transistor
href: zk/Transistors.md
type: markdown
snippet:
  The [transistor](Transistors.md) is
  the electrical component that enables us to represent given voltage ranges as
  being 'on' or 'off'.


title: foreign_keys
href: zk/Foreign_keys_in_SQL.md
type: markdown
snippet:
  DynamoDB is "NoSQL" because it does not support #SQL queries and is
  non-relational meaning there cannot be JOIN operations via
  [foreign_keys](Foreign_keys_in_SQL.md)


title: zk/Docker_architecture
href: zk/Docker_architecture
type: wiki-link
snippet:
  Cloud-based or virtual server (virtual machine), basically a hypervisor
    (compare [[zk/Docker_architecture]])


title: kernel
href: zk/The_Kernel.md
type: markdown
snippet:
  A running Node application is a single running process. Like everything that
  happens within the OS, a process is managed by the
  [kernel](The_Kernel.md) that dispatches operations to the CPU
  in a clock cycle. A thread is a sequence of code that resides within the process
  and utilises its memory pool (the amount of memory assigned by the kernel to the
  Node process). The Event Loop runs on CPU ticks: a tick is a single run of the
  Event Loop.


title: call stack
href: zk/Call_stack.md
type: markdown
snippet:
  The Event Loop comprises six phases. The Event Loop starts at the moment Node
  begins to execute your `index.js` file or any other application entry point.
  These six phases create one cycle, or loop, equal to one **tick**. A Node.js
  process exits when there is no more pending work in the Event Loop, or when
  `process.exit()` is called manually. A program only runs for as long as there
  are tasks queued in the Event Loop, or present on the
  [call stack](Call_stack.md).


title: call stack
href: zk/Call_stack.md
type: markdown
snippet:
  At the beginning of this phase the Event Loop updates its own time. Then it
       checks a queue, or pool, of timers. This queue consists of all timers that
       are currently set. The Event Loop takes the timer with the shortest wait
       time and compares it with the Event Loop's current time. If the wait time
       has elapsed, then the timer's callback is queued to be called once the
       [call stack](Call_stack.md) is empty.


title: https://blog.appsignal.com/2022/07/20/an-introduction-to-multithreading-in-nodejs.html
href: https://blog.appsignal.com/2022/07/20/an-introduction-to-multithreading-in-nodejs.html
type: implicit
snippet:
  https://blog.appsignal.com/2022/07/20/an-introduction-to-multithreading-in-nodejs.html
  https://school.geekwall.in/p/Bk2xFs1DV


title: syntactic
href: zk/Syntax_of_sentential_logic.md
type: markdown
snippet:
  Derivation rules are
  [syntactic](Syntax_of_sentential_logic.md) rather
  than semantic. They are applied on the basis of their form rather than on the
  basis of the truth conditions of the sentences they are applied to.


title: CREATE TABLE
href: zk/Create_an_SQL_table.md
type: markdown
snippet:
  The output will be represented as a table but it is virtual, not an actual
  table. (If you wish to actually create a table or a view off the back of a join
  operation you should combine the join with the
  [`CREATE TABLE`](Create_an_SQL_table.md) command etc.)


title: contradiction
href: zk/Logical_truth_and_falsity.md#logical-falsity
type: markdown
snippet:
  A
  [contradiction](Logical_truth_and_falsity.md#logical-falsity)
  has very important consequences for reasoning because if a set of propositions
  is inconsistent, any other proposition is derivable from it.


title: negation elimination
href: zk/Negation_Elimination.md
type: markdown
snippet:
  Here we want to derive some proposition $Q$. If we can derive a contradiction
  from its negation as an assumption then, by the
  [negation elimination](Negation_Elimination.md)) rule, we can
  assert $Q$. This is why contradictions should be avoided in arguments, they
  'prove' everything which, by association, undermines any particular premise you
  are trying to assert.


title: derivation
href: zk/Formal proofs in propositional logic.md
type: markdown
snippet:
  Propositions $P$ and $Q$ are equivalent in a system of
  > [derivation](Formal%20proofs%20in%20propositional%20logic.md) for
  > propositional logic if $Q$ is derivable from $P$ and $P$ is derivable from
  > $Q$.


title: material biconditional
href: zk/Biconditional_Introduction.md
type: markdown
snippet:
  Note that the property of equivalence stated in terms of derivablity above is
  identical to the derivation rule for the
  [material biconditional](Biconditional_Introduction.md):


title: consistently
href: zk/Consistency.md
type: markdown
snippet:
  A proposition is logically indeterminate if it is neither logically true or
  logically false. This is to say: it can be both [consistently](Consistency.md)
  asserted and consistently denied.


title: logical consistency
href: zk/Logical_consistency.md
type: markdown
snippet:
  In distinguishing the properties of
  [logical consistency](Logical_consistency.md) and
  [validity](Validity_and_entailment.md) we make tacit use
  of the notion of **possibility**. This is because when we consider the validity
  of an argument we are assessing truth-conditions and this consists in asking
  ourselves what could or could not be the case: were it such that _P_, then it
  would be the case that _Q_. It is important to understand what possibility means
  in the context of logic and how it differs from what we might mean ordinarily
  when we use the term.


title: logical truth
href: zk/Logical_truth_and_falsity.md#logical-truth
type: markdown
snippet:
  A proposition is _logically necessary_ if it is true in every logically possible
  circumstance which is to say: true on every possible truth functional
  assignment. Necessity and
  [logical truth](Logical_truth_and_falsity.md#logical-truth)
  are therefore synonyms: anything that is logically true (a tautology) is true by
  necessity (could not be otherwise.)


title: consistency
href: zk/Logical_consistency.md
type: markdown
snippet:
  Neither proposition can be true because the truth of the first clause is
  contradicted by the second. By the principle of
  [consistency](Logical_consistency.md), it is not
  possible for both clauses to be true at once therefore the proposition, overall
  has the truth value of false.


title: validity
href: zk/Validity_and_entailment.md
type: markdown
snippet:
  If an argument contains premises which are logically false than this argument
    will perforce be valid. This is because one cannot consistently assert the
    premises and deny the conclusion which is the definition of
    [validity](Validity_and_entailment.md). However the
    _reason_ why one cannot consistently assert the premises and deny the
    conclusions is because one cannot consistently assert the premises - they
    conflict with each other. Furthermore as the argument contains false premises,
    it cannot be sound.


title: global process object
href: zk/Process_object.md
type: markdown
snippet:
  To determine the current environment we can use the variable
  **`process.env.NODE_ENV`** from the
  [global process object](Process_object.md).
  This works universally regardless of the kind of Node app we are building.


title: environment variable
href: zk/Environmental_and_shell_variables.md
type: markdown
snippet:
  `NODE_ENV` is a bash
  [environment variable](Environmental_and_shell_variables.md)
  like any other. So we can set it in the normal way:


title: Config
href: zk/node-config
type: markdown
snippet:
  We use the third-party [Config](node-config)
  package to manage different configurations based on the environment.


title: environmental variables
href: zk/Environmental_and_shell_variables.md
type: markdown
snippet:
  We can do so securely by utilising
  [environmental variables](Environmental_and_shell_variables.md)
  alongside the config pacakage.


title: React_useEffect
href: zk/React_useEffect.md
type: markdown
snippet:
  Note that the syntax is similar to [React_useEffect](React_useEffect.md): there is a
  dependency array. The effect is the same: the function contained within
  `useCallback` will only re-rendered if one of these dependencies changes.
  However (see next section) the function will run in its memoized form on every
  click.


title: CPU
href: zk/CPU_architecture.md
type: markdown
snippet:
  When a [CPU](CPU_architecture.md) executes a program,
  it needs a place to store the program's **instructions** and **related data**.
  This is the role of memory.


title: transistor
href: zk/Transistors.md
type: markdown
snippet:
  In a DRAM cell, each bit of data is stored as a charge in a capacitor. The
  presence of charge represents a '1' bit and the absence of charge represents a
  '0' bit. Each of these cells is paired with a
  [transistor](Transistors.md) that
  controls the reading and writing of data.


title: charge
href: zk/Current.md
type: markdown
snippet:
  However capacitors lose
  [charge](Current.md) over time due
  to leaks. As a result DRAM is memory that needs to be refreshed (recharged)
  frequently. For this reason and because it only uses one transistor and
  capacitor per bit, DRAM is the less expensive form of volatile memory.


title: flip flops
href: zk/Flip_flops.md
type: markdown
snippet:
  SRAM uses [flip flops](Flip_flops.md)
  to store the bits. It also uses multiple transistors per bit. This makes it
  faster than DRAM but more expensive. DRAM is at least ten times slower than
  SRAM.


title: bootstrapping
href: zk/Boot_process.md
type: markdown
snippet:
  The following steps outline the way in which memory interacts with the processor
  during computational cycles, once the
  [bootstrapping](Boot_process.md) process has completed and
  the OS kernel is itself loaded into memory.


title: system bus
href: zk/Bus.md
type: markdown
snippet:
  The instruction at the first address is sent to the CPU, travelling accross
     the data bus part of the [system bus](Bus.md).


title: chipset
href: zk/Chipset_and_controllers.md
type: markdown
snippet:
  The CPU processes this instruction and then sends a request accross the
     address bus part of the system bus for the next instruction to the memory
     controller within the
     [chipset](Chipset_and_controllers.md).


title: DRAM
href: zk/Memory.md#dram
type: markdown
snippet:
  The chipset finds where this instruction is stored within the
     [DRAM](Memory.md#dram) and issues a request to
     have it read out and send to the CPU over the data bus.


title: logarithm
href: zk/Logarithms.md
type: markdown
snippet:
  We need to reverse this formula to find out how many bits we need to represent a
  given number of addresses. We can do this with a
  [logarithm](Logarithms.md).


title: hexadecimal numbers
href: zk/Hexadecimal_number_system.md
type: markdown
snippet:
  This is hard to parse so we can instead use
  [hexadecimal numbers](Hexadecimal_number_system.md)
  to represent the addresses:


title: binary encoding
href: zk/Binary_encoding.md
type: markdown
snippet:
  By itself, the the data is meaningless but we know from
  [binary encoding](Binary_encoding.md) that the
  binary data will correspond to some meaningful data, such as a character or a
  colour, depending on the encoding scheme used. The above table could correspond
  to the characters for 'A', 'B' and 'C' in the ASCII encoding scheme:


title: ports
href: zk/Ports.md
type: markdown
snippet:
  We can control which middleware we run via the Node envrionment variables:
  `process.env` (see for instance [ports](Ports.md)).


title: tables
href: zk/Relational_database_architecture.md#table
type: markdown
snippet:
  Although Mongo is not a relational database it has a structure that we can
  understand in relation to that paradigm. A **database** is obviously the overall
  structure. It comprises **collections** which are organised sets of data that
  are analagous to [tables](Relational_database_architecture.md#table)
  in RDBs. Within each collection are a series of **documents** which we can think
  of as being equivalent to [rows](Relational_database_architecture.md)
  in RDB table: units that comprise the collection.


title: ps
href: zk/Processes.md
type: markdown
snippet:
  We can use [ps](Processes.md) to list the
  currently running processes but it does not provide much information about the
  resource metrics or how the process changes over time. We can use `top` to get
  more information.


title: virtual memory
href: zk/Virtual_memory_and_the_MMU.md
type: markdown
snippet:
  The total amount of
      [virtual memory](Virtual_memory_and_the_MMU.md) used by
      the process including: program code, data, shared libraries, pages that have
      been swapped, pages that have been mapped but not used.


title: buffer
href: zk/Role_of_memory_in_computation.md#relation-between-cache-and-buffers
type: markdown
snippet:
  Total kbs currently in
        [buffer](Role_of_memory_in_computation.md#relation-between-cache-and-buffers)
        and not written


title: cache
href: zk/Role_of_memory_in_computation.md#relation-between-cache-and-buffers
type: markdown
snippet:
  Total amount of virtual memory in the
        [cache](Role_of_memory_in_computation.md#relation-between-cache-and-buffers)


title: swapped
href: zk/Swap_space.md
type: markdown
snippet:
  Distinguishes amount of memory
      [swapped](Swap_space.md) in (`si`) to memory and
      swapped out (`so`) to disk


title: kernel
href: zk/The_Kernel.md
type: markdown
snippet:
  A system call is when a process requests a service from the
  [kernel](The_Kernel.md), for instance an I/O operation to
  memory. We can trace these system calls with `strace`.


title: MMU
href: zk/Virtual_memory_and_the_MMU.md
type: markdown
snippet:
  We know that processes primarily interact with virtual memory in the form of
  pages which are then translated to physical blocks by the kernel via the
  [MMU](Virtual_memory_and_the_MMU.md). There are several tools
  which provide windows onto this process.


title: buffers and caches
href: zk/Role_of_memory_in_computation.md#relation-between-cache-and-buffers
type: markdown
snippet:
  `free` displays the total amount of free and¬used physical and swap memory in
  the system, as well as the
  [buffers and caches](Role_of_memory_in_computation.md#relation-between-cache-and-buffers)
  used by the kernel.


title: CPU
href: zk/CPU_architecture.md
type: markdown
snippet:
  The motherboard is the foundation of a computer. It allocates power and allows
  communication to and between the
  [CPU](CPU_architecture.md),
  [RAM](Memory.md),
  [harddisk](What_are_disks.md) and all other hardware
  components.


title: build context
href: zk/Creating_a_Docker_image.md#creating-a-docker-image
type: markdown
snippet:
  Each of the files listed below would be saved to the same source directory which
  would then form the basis of the
  [build context](Creating_a_Docker_image.md#creating-a-docker-image).


title: process.env
href: zk/Managing_environments.md
type: markdown
snippet:
  In the example, the database connection information in the Node source is coming
  from the
  [`process.env`](Managing_environments.md)
  object, which itself is sourcing the values `MYSQL_HOST`, `MYSQL_PASSWORD` etc
  from the Docker compose file. Therefore these values are hardcoded there.


title: semantic versioning
href: zk/Semantic_versioning.md
type: markdown
snippet:
  `npm update` only updates from _current_ to _wanted_. In other words it only
  updates in accordance with your caret and tilde rules applied to
  [semantic versioning](Semantic_versioning.md).


title: event listeners
href: zk/Events module.md#event-emitters
type: markdown
snippet:
  While we may not know the specific port, whatever it is, it will be accessible
  via the `PORT` environment variable. So we can use this when writing our
  [event listeners](Events%20module.md#event-emitters):


title: any
href: zk/Any.md
type: markdown
snippet:
  `Object` is a valid type declaration in TS but it is not particularly helpful
  since it becomes similar to using [any](Any.md) given that most primitive
  types in JavaScripts prototypically inherit from an Object.


title: custom types
href: zk/Custom_types_in_TypeScript.md
type: markdown
snippet:
  Generally, when you use objects in TypeScript you type them as
  [custom types](Custom_types_in_TypeScript.md).


title: model
href: zk/Create_collections_and_documents_with_Mongoose.md#models
type: markdown
snippet:
  Now we will query the collection. This capability is provided via the Mongoose
  schema class we used to create the `Course`
  [model](Create_collections_and_documents_with_Mongoose.md#models).
  We have the following methods available to use from the schema:


title: React_useEffect
href: zk/React_useEffect.md#cleanup-functions
type: markdown
snippet:
  As the warning suggests, this can be resolved using the cleanup parameter within
  [React_useEffect](React_useEffect.md#cleanup-functions).


title: Application state management
href: zk/Application_state_management_with_React_hooks.md
type: markdown
snippet:
  In the examples above we have only been consuming state that is owned by the
  provider however in most scenarios you will also want to update the state from a
  consumer. This is best achieved by combining `useContext` with a reducer and is
  detailed in [Application state management](Application_state_management_with_React_hooks.md).


title: lifecyle methods
href: zk/Lifecycle_methods.md
type: markdown
snippet:
  `useEffect` enshrines but also simplifies the
  [lifecyle methods](Lifecycle_methods.md) that are used with
  class-based React components.


title: lifecycle methods
href: zk/Lifecycle_methods.md
type: markdown
snippet:
  The syntax of the `useEffect` hook also allows you to handle cleanup: something
  you want to do when the component unmounts (another example of how this hook
  recasts the traditional [lifecycle methods](Lifecycle_methods.md))
  . In addition to running on unmount, the cleanup function will run before the
  effect runs again (i.e. when it runs in response to a change in one of the
  elements of the dependency araray). This is chiefly used to prevent
  [memory leaks](Memory_leaks.md) and the
  ['update on unmounted component error'](React_errors.md#state-update-on-unmounted-component).


title: AWS Lambda handler function
href: zk/Lambda_handler_function.md
type: markdown
snippet:
  Let's walk through the above example making reference to the general structure
  of the
  [AWS Lambda handler function](Lambda_handler_function.md):


title: ACID principle
href: zk/ACID_principle.md
type: markdown
snippet:
  This is essential for carrying out operations across database tables and for
  creating and deleting database entires in accordance with the
  [ACID principle](ACID_principle.md). It is also a safeguard: it means
  you can always identify a record by itself and don't have to rely on generic
  queries to identify it.


title: recursive
href: zk/Recursion.md
type: markdown
snippet:
  Goal analysis is a [recursive](Recursion.md) strategy which
  proceeds by using a 'goal' proposition to guide the construction of intermediary
  derivations.


title: valid
href: zk/Validity_and_entailment.md#validity
type: markdown
snippet:
  Assume that we want to show that an argument is
  [valid](Validity_and_entailment.md#validity). Then our
  ultimate goal is to derive the conclusion from the premises we are given. We
  first ask ourselves: _which propositions if we could derive them, would allow us
  to easily derive the conclusion_? (For example, these propositions might be two
  simple propositions that when combined with
  [Conjunction Introduction](Conjunction_Introduction.md) give us
  the conclusion.) Deriving these propositions then becomes the new intermediate
  goal.


title: Conjunction Introduction
href: zk/Conditional_Introduction.md
type: markdown
snippet:
  First, we consider what is the easiest possible way of achieving the proposition
  $(L \lor A) \land D$. Clearly it is to separately derive each disjunct
  ($L \lor A$ and $D$) and then combine them with
  [Conjunction Introduction](Conditional_Introduction.md). This
  provides us with our first goal: to derive each of the separate conjuncts.


title: Conjunction Elimination
href: zk/Conjunction Elimination.md
type: markdown
snippet:
  Let's start with $D$: where does it occur in the assumptions? It occurs in the
  compound $(\lnot N \rightarrow L) \land (D \leftrightarrow \lnot N)$, but only
  in the first conjunct. We can get this simply but applying
  [Conjunction Elimination](Conjunction%20Elimination.md).


title: Biconditional Elimination
href: zk/Biconditional_Elimination.md
type: markdown
snippet:
  Now we just need to get $D$ from the proposition at line 3. This is easy since
  we already have access to the consequent of the biconditional at line 1.
  Therefore we can apply
  [Biconditional Elimination](Biconditional_Elimination.md)) at line
  3 to get $D$. We are now halfway there:


title: Conjunction Elimination
href: zk/Conjunction_Elimination.md
type: markdown
snippet:
  Next we need to turn our attention to deriving $L \lor A$. How can we obtain $L$
  ? Well it is contained within the first conjunct of the assumption on line 2.
  Again, we can get this through the application of
  [Conjunction Elimination](Conjunction_Elimination.md). Now, how do
  we get $L$ from $(\lnot N \rightarrow L)$? Well, we already have the antecedent
  $\lnot N$ as an assumption on the first line, so we can use
  [Conditional Elimination](Conditional_Elimination.md) to derive
  $L$. These two steps give us:


title: Disjunction Introduction
href: zk/Disjunction_Introduction.md
type: markdown
snippet:
  Now we need to get from $L$ to $L \lor A$. This is really straightforward
  because by using
  [Disjunction Introduction](Disjunction_Introduction.md)) we can
  get from any sentence to a disjunction. Finally, having assembled all the
  constituent parts of the conjunction that is the conclusion, we can combine them
  with [Conjunction Introduction](Conjunction_Introduction.md) as we
  had planned at the outset.


title: Conjunction Introduction
href: zk/Conjunction_Introduction.md
type: markdown
snippet:
  The requirements here could easily mislead us. We see that the target
  proposition is a conjunction so we might think that the best strategy is to seek
  to derive each conjunct and then combine them via
  [Conjunction Introduction](Conjunction_Introduction.md)).


title: Biconditional Elimination
href: zk/Biconditional_Elimination.md
type: markdown
snippet:
  Actually, if we look more closely, there is a better approach. The target
  proposition is contained in the first premise as the consequent to the
  biconditional ($\lnot L \leftrightarrow [X \land (\lnot S \lor B)]$). A better
  approach is therefore to seek to derive the antecedent ($\lnot L$) and then use
  [Biconditional Elimination](Biconditional_Elimination.md) to
  extract the target sentence which is the consequent.


title: theorems
href: zk/Theorems_and_empty_sets.md#theorems-and-empty-sets
type: markdown
snippet:
  When we are proving
  [theorems](Theorems_and_empty_sets.md#theorems-and-empty-sets)
  we do not have a set of assumptions to work from when constructing the proof. We
  must derive the target sentence from the 'empty set' which is the target
  sentence itself. It is therefore like a process of reverse engineering.


title: Disjunction Elimination
href: zk/Disjunction_Elimination.md
type: markdown
snippet:
  Our starting assumption is to a disjunction. Thus we can apply
    [Disjunction Elimination](Disjunction_Elimination.md) to show
    that our goal sentence $\lnot(A \land B)$ follows from each of the disjuncts
    ($\lnot A$ and $\lnot B$) in dedicated sub-proofs. If we can do this, we have
    the right to derive $\lnot (A \land B)$.


title: Disjunction Elimination
href: zk/Disjunction_Elimination.md
type: markdown
snippet:
  Having done this, we can discharge the
    [Disjunction Elimination](Disjunction_Elimination.md) sub-proofs
    and derive $\lnot (A \land B)$ from $\lnot A \lor \lnot B$


title: Negation Elimination
href: zk/Negation_Elimination.md
type: markdown
snippet:
  We will do this by assuming the negation of what we want to prove
    ($\lnot (\lnot A \lor \lnot B)$) and then apply
    [Negation Elimination](Negation_Elimination.md) to get
    $\lnot A \lor \lnot B$.


title: Negation Elimination
href: zk/Negation_Elimination.md
type: markdown
snippet:
  This requires us to derive a contradiction. We get this on lines 23 and 24.
    This requires as previous steps that we have two sub-proofs that use
    [Negation Elimination](Negation_Elimination.md) to release $A$
    and $B$


title: atomic and molecular propositions
href: zk/Atomic_and_molecular_propositions.md
type: markdown
snippet:
  These definitions provide a formal specification of the concepts of
  [atomic and molecular propositions](Atomic_and_molecular_propositions.md)
  introduced previously.


title: derivation
href: zk/Formal_proofs_in_propositional_logic.md#derivation-rules
type: markdown
snippet:
  We know that when we construct a
  [derivation](Formal_proofs_in_propositional_logic.md#derivation-rules)
  we start from a set of assumptions and then attempt to reach a proposition that
  is a consequence of the starting assumptions. However it does not always have to
  be the case that the starting set contains members. The set can in fact be
  empty.


title: logically determinant
href: zk/Logical_indeterminacy.md
type: markdown
snippet:
  We know that
  [logically determinant](Logical_indeterminacy.md)
  propositions express a truth value. When simple propositions are joined with a
  connective to make a compound proposition they also have a truth value. This is
  determined by the nature of the connective and the truth value of the
  constituent propositions. We therefore call connectives of this nature truth
  _functional_ connectives since the **truth value of the compound is a function
  of the truth values of its components**.


title: binary encoding
href: Binary_encoding
type: wiki-link
snippet:
  Two's complement divides the available word length (see
  [[Binary_encoding|binary encoding]]) into two subsets: one for negative integrs
  and one for positive integers.


title: signed_and_unsigned_numbers
href: Signed_and_unsigned_numbers
type: wiki-link
snippet:
  [[Signed_and_unsigned_numbers|signed_and_unsigned_numbers]],
  [[Binary_addition|binary addition]], [[Signed_magnitude_representation]]


title: query
href: zk/Querying_a_Mongo_collection.md
type: markdown
snippet:
  With this approach we first execute a
  [query](Querying_a_Mongo_collection.md) to retrieve the document we
  want to edit and then make the change. We use the `findById` method to identify
  the document by its UUID and then `set` to update specified properties on the
  document. The `set` method is one of many operators that can be used to update
  values. For example there is also built-in operators for increment, renaming,
  multiplying values.


title: Joi
href: zk/Validation.md
type: markdown
snippet:
  What is the relationship between this Mongoose validation and the
  [Joi](Validation.md) validation that we
  use when validating API requests in Node/Express? They complement each other. We
  use Joi to validate the client request to the API. If this is valid, the process
  would then move onto the next stage which would be transforming the data from a
  REST request to a database request implemented through Mongoose, where a second
  layer of validation would appy. We would also have validation on the
  client-side.


title: event queue
href: zk/Event_loop.md
type: markdown
snippet:
  Every method associated with `fs` has a _blocking_ and _asynchronous_
  implementation. The former obviously blocks the
  [event queue](Event_loop.md), the
  latter does not.


title: event emitter
href: zk/events.md
type: markdown
snippet:
  An HTTP server is another instance of an
  [event emitter](events.md)). It
  therefore has all the same methods as the `EventEmitter` class: `on`, `emit`,
  `addListener` etc. This demonstrates again how much of Node's core functionality
  is based on event emitters.


title: event listeners
href: zk/events.md
type: markdown
snippet:
  Typically we want to write and read data that the user provides. To do this we
  need to wait on that event. So we use Node's asynchonous
  [event listeners](events.md). We wait
  on the `data` event:


