{"id":19704556,"url":"https://github.com/phurin-git/dev-playground","last_synced_at":"2025-08-10T08:39:56.325Z","repository":{"id":249512599,"uuid":"831711964","full_name":"phurin-git/dev-playground","owner":"phurin-git","description":"Welcome to DevPlayground! This repository serves as a comprehensive coding workspace where I practice my skills in various programming languages and frameworks.","archived":false,"fork":false,"pushed_at":"2024-09-16T16:15:40.000Z","size":2493,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-27T18:09:48.286Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phurin-git.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-21T12:04:10.000Z","updated_at":"2024-09-25T05:21:33.000Z","dependencies_parsed_at":"2024-11-11T21:39:42.715Z","dependency_job_id":null,"html_url":"https://github.com/phurin-git/dev-playground","commit_stats":null,"previous_names":["phurin-git/devplayground","phurin-git/dev-playground"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/phurin-git/dev-playground","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phurin-git%2Fdev-playground","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phurin-git%2Fdev-playground/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phurin-git%2Fdev-playground/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phurin-git%2Fdev-playground/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phurin-git","download_url":"https://codeload.github.com/phurin-git/dev-playground/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phurin-git%2Fdev-playground/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269698261,"owners_count":24461193,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-10T02:00:08.965Z","response_time":71,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-11T21:23:14.976Z","updated_at":"2025-08-10T08:39:56.295Z","avatar_url":"https://github.com/phurin-git.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# DevPlayground\n\n Welcome to DevPlayground! This repository serves as a comprehensive coding workspace where I practice my skills in various programming languages and frameworks.\n\n## Content\n\n- [CSS Cheat Sheet](README.md/#CSS-Cheat-Sheet)\n  - [Selectors](README.md/#Selectors)\n  - [Box Model](README.md/#CSS-Cheat-Sheet)\n  - [Text and Font](README.md/#CSS-Cheat-Sheet)\n  - [Background](README.md/#CSS-Cheat-Sheet)\n  - [Display and Positioning](README.md/#Display-and-Positioning)\n  - [Flexbox](README.md/#Flexbox)\n  - [Grid](README.md/#Grid)\n  - [Animation and Transitions](README.md/#Animation-and-Transitions)\n  - [Miscellaneous](README.md/#Miscellaneous)\n- [JS Cheat Sheet](README.md/#JS-Cheat-Sheet)\n  - [Array Methods](README.md/#Array-Methods)\n  - [ES6 (Destructuring)](README.md/#ES6-(Destructuring))\n  - [DOM \u0026 Events](README.md/#DOM-\u0026-Events)\n  - [Semantics \u0026 Accessibility](README.md/#Semantics-\u0026-Accessibility)\n  - [Synchrony \u0026 Asynchrony](README.md/#Synchrony-\u0026-Asynchrony)\n  - [Classes](README.md/#Classes)\n- [TypeScript Cheat Sheet](README.md/#TypeScript-Cheat-Sheet)\n  - [Basics](README.md/#Basics)\n  - [More Types](README.md/#More-Types)\n  - [Functions, Classes, \u0026 Enums](README.md/#Functions,-Classes,-\u0026-Enums)\n  - [Generics](README.md/#Generics)\n- [React Cheat Sheet](README.md/#React-Cheat-Sheet)\n  - [Intro to React](README.md/#Intro-to-React)\n  - [JSX](README.md/#JSX)\n  - [Class Components](README.md/#Class-Components)\n  - [Functional Components](README.md/#Functional-Components)\n  - [CSS Styling in React](README.md/#CSS-Styling-in-React)\n  - [Hooks and useState](README.md/#Hooks-and-useState)\n  - [Hooks and useEffect](README.md/#Hooks-and-useEffect)\n  - [Conditional Rendering](README.md/#Conditional-Rendering)\n  - [Ternary Operators and \u0026\u0026](README.md/#Ternary-Operators-and-\u0026\u0026)\n  - [Lists and Maps](README.md/#Lists-and-Maps)\n- [SQL Cheat Sheet](README.md/#SQL-Cheat-Sheet)\n- [Node.js Cheat Sheet](README.md/#Nodejs-Cheat-Sheet)\n  - [Intro to Node.js](README.md/#Intro-to-Nodejs)\n  - [Client vs Servers](README.md/#Client-vs-Servers)\n  - [Communicating with an API](README.md/#Communicating-with-an-API)\n  - [HTTP Requests](README.md/#HTTP-Requests)\n  - [HTTP Request Responses](README.md/#HTTP-Request-Responses)\n- [Express.js Cheat Sheet](README.md/#Expressjs-Cheat-Sheet)\n  - [Introduction-to-ExpressJS](README.md/#Introduction-to-ExpressJS)\n  - [Request and Response Objects](README.md/#Request-and-Response-Objects)\n  - [ExpressJS Route Parameters](README.md/#ExpressJS-Route-Parameters)\n  - [Middleware in Express](README.md/#Middleware-in-Express)\n  - [Express Router](README.md/#Express-Router)\n  - [Express Error Handling](README.md/#Express-Error-Handling)\n  - [Structuring GET Endpoints](README.md/#Structuring-GET-Endpoints)\n  - [Structuring POST Endpoints](README.md/#Structuring-POST-Endpoints)\n  - [Structuring DELETE Endpoints](README.md/#Structuring-DELETE-Endpoints)\n  - [Structuring PUT Endpoints](README.md/#Structuring-PUT-Endpoints)\n  - [Connecting to a Database](README.md/#Connecting-to-a-Database)\n  - [Database Interactions](README.md/#Database-Interactions)\n- [Python Cheat Sheet](/Python%20Developer.ipynb)\n\n## CSS Cheat Sheet\n\n### Selectors\n\n- `*`: Universal selector\n- `element`: Type selector (e.g., `p`, `h1`)\n- `.class`: Class selector (e.g., `.container`)\n- `#id`: ID selector (e.g., `#main`)\n- `element, element`: Grouping selector (e.g., `h1, h2, h3`)\n- `element element`: Descendant selector (e.g., `ul li`)\n- `element \u003e element`: Child selector (e.g., `div \u003e p`)\n- `element + element`: Adjacent sibling selector (e.g., `h1 + p`)\n- `element ~ element`: General sibling selector (e.g., `h1 ~ p`)\n- `[attribute]`: Attribute selector (e.g., `[type=\"text\"]`)\n\n### Box Model\n\n- `width`: Width of the element\n- `height`: Height of the element\n- `padding`: Space inside the element, around content\n  - `padding-top`\n  - `padding-right`\n  - `padding-bottom`\n  - `padding-left`\n- `margin`: Space outside the element, around border\n  - `margin-top`\n  - `margin-right`\n  - `margin-bottom`\n  - `margin-left`\n- `border`: Border around the element\n  - `border-width`\n  - `border-style`: solid, dashed, dotted, etc.\n  - `border-color`\n\n### Text and Font\n\n- `color`: Text color\n- `font-family`: Font family (e.g., `Arial, sans-serif`)\n- `font-size`: Font size (e.g., `16px`, `1em`)\n- `font-weight`: Font weight (e.g., `bold`, `normal`, `700`)\n- `line-height`: Line height\n- `text-align`: Text alignment (e.g., `left`, `center`, `right`, `justify`)\n- `text-decoration`: Text decoration (e.g., `none`, `underline`, `line-through`)\n- `text-transform`: Text transformation (e.g., `uppercase`, `lowercase`, `capitalize`)\n- `letter-spacing`: Space between letters\n- `word-spacing`: Space between words\n\n### Background\n\n- `background-color`: Background color\n- `background-image`: Background image (e.g., `url('image.jpg')`)\n- `background-repeat`: Repeat behavior (e.g., `no-repeat`, `repeat-x`, `repeat-y`)\n- `background-position`: Position of background image (e.g., `center`, `top right`)\n- `background-size`: Size of background image (e.g., `cover`, `contain`)\n- `background-attachment`: Attachment behavior (e.g., `scroll`, `fixed`)\n\n### Display and Positioning\n\n- `display`: Display type (e.g., `block`, `inline`, `inline-block`, `flex`, `grid`, `none`)\n- `position`: Position type (e.g., `static`, `relative`, `absolute`, `fixed`, `sticky`)\n- `top`, `right`, `bottom`, `left`: Offset properties for positioned elements\n- `z-index`: Stack order of an element\n\n### Flexbox\n\n- `display: flex`: Enables flexbox layout\n- `flex-direction`: Direction of flex items (e.g., `row`, `column`)\n- `justify-content`: Alignment along the main axis (e.g., `flex-start`, `center`, `space-between`, `space-around`)\n- `align-items`: Alignment along the cross axis (e.g., `flex-start`, `center`, `stretch`)\n- `flex-wrap`: Wrapping behavior (e.g., `nowrap`, `wrap`, `wrap-reverse`)\n- `flex`: Shorthand for `flex-grow`, `flex-shrink`, and `flex-basis`\n\n### Grid\n\n- `display: grid`: Enables grid layout\n- `grid-template-columns`: Defines columns (e.g., `repeat(3, 1fr)`, `200px 1fr`)\n- `grid-template-rows`: Defines rows (e.g., `repeat(3, 100px)`, `auto 1fr`)\n- `gap`: Space between grid items\n- `grid-column`: Shorthand for `grid-column-start` and `grid-column-end`\n- `grid-row`: Shorthand for `grid-row-start` and `grid-row-end`\n\n### Animation and Transitions\n\n- `transition`: Shorthand for transition properties (e.g., `all 0.3s ease`)\n  - `transition-property`: Property to transition\n  - `transition-duration`: Duration of transition\n  - `transition-timing-function`: Timing function (e.g., `ease`, `linear`)\n  - `transition-delay`: Delay before starting\n- `animation`: Shorthand for animation properties (e.g., `name duration timing-function delay iteration-count direction fill-mode`)\n  - `@keyframes`: Define animation (e.g., `@keyframes slide { 0% { left: 0 } 100% { left: 100% } }`)\n\n### Miscellaneous\n\n- `overflow`: Handling of overflow content (e.g., `visible`, `hidden`, `scroll`, `auto`)\n- `opacity`: Opacity level (e.g., `1`, `0.5`)\n- `cursor`: Mouse cursor style (e.g., `pointer`, `default`)\n- `visibility`: Visibility of an element (e.g., `visible`, `hidden`)\n\n## JS Cheat Sheet\n\n### Array Methods\n\n**`map()`**\n method creates a new array populated with the results of calling a provided function on every element in the calling array.\n\n```javascript\nlet newArray = array.map(function(currentValue, index, arr), thisValue)\n\n/*\n- `currentValue`        : The current element being processed in the array.\n- `index` (Optional)    : The index of the current element being processed in the array.\n- `arr` (Optional)      : The array `map` was called upon.\n- `thisValue` (Optional): Value to use as `this` when executing the callback.\n*/\n```\n\n**`filter()`** method creates a new array with all elements that pass the test implemented by the provided function.\n\n```javascript\nlet newArray = array.filter(function(currentValue, index, arr), thisValue)\n\n/*\n- `currentValue`        : The current element being processed in the array.\n- `index` (Optional)    : The index of the current element being processed in the array.\n- `arr` (Optional)      : The array `filter` was called upon.\n- `thisValue` (Optional): Value to use as `this` when executing the callback.\n*/\n```\n\n**`reduce()`** method executes a reducer function (that you provide) on each element of the array, resulting in a single output value.\n\n```javascript\nlet value = array.reduce(function(accumulator, currentValue, index, arr), initialValue)\n\n/*\n- `accumulator`             : The accumulator accumulates the callback's return values it is the accumulated value previously returned in the last invocation of the callback, or initialValue, if supplied.\ncurrentValue                : The current element being processed in the array.\n- `index` (Optional)        : The index of the current element being processed in the array.\n- `arr` (Optional)          : The array `reduce` was called upon.\n- `initialValue` (Optional) : A value to use as the first argument to the first call of the callback. If no initial value is supplied, the first element in the array will be used and skipped.\n*/\n```\n\n### ES6 (Destructuring)\n```javascript\n// Array Destructuring\nconst [a, b] = [1, 2]\nconst [a, , b] = [1, 2, 3]\nconst [a = 1, b = 2] = [undefined, 3]\nconst [a, ...rest] = [1, 2, 3, 4]\n\n// Object Destructuring\nconst {a, b} = {a: 1, b: 2}\nconst {a: x, b: y} = {a: 1, b: 2}\nconst {a = 10, b = 5} = {a: 3}\n\n// Combine Destructuring\nconst props = [\n  {id: 1, name: 'Alice'},\n  {id: 2, name: 'Bob'}\n]\n\nconst [{name: name1}, {name: name2}] = props\n```\n\n### DOM \u0026 Events\n\n**HTML document's tree**\n```\nDocument  -\u003e  document\n└── html\n    ├── head  -\u003e  document.head\n    │   └── title\n    │       └── \"Example\"\n    └── body  -\u003e  document.body\n        ├── h1  -\u003e  document.body.children[0] | document.body.firstElementChild\n        │   └── \"Hello, World!\"\n        ├── p   -\u003e  document.body.children[1]\n        │   └── \"This is an example.\"\n        └── div -\u003e  document.body.children[2]\n            └── p\n                └── \"Another paragraph inside a div.\"\n```\n\n```javascript\nconst paragraph = document.createElement('p') // New Element\nconst span = document.createElement('span')\ndocument.body.appendChild(paragraph)          // Append Element\nparagraph.appendChild(span)\nparagraph.removeChild(span)                   // Remove Element\n\nlet count = 0\nconst printCount = (element) =\u003e {\n  count++\n  element.innerHTML = count\n}\n\nparagraph.onclick = printCount                // Set event properties\nparagraph.addEventListener(\"dbclick\", () =\u003e {this.innerHTML = \"Double Clicked!\"}) // Also can remove event with `element.removeEventListener(event, callback)`\n\n// For more event see MDN Docs -\u003e https://developer.mozilla.org/en-US/docs/Web/API/Element#events\n```\n\n### Semantics \u0026 Accessibility\n\nIn programming, Semantics refers to the meaning of a piece of code — for example \"what effect does running that line of JavaScript have?\", or \"what purpose or role does that HTML element have\" (rather than \"what does it look like?\".)\nMore detials – [Here](https://developer.mozilla.org/en-US/docs/Glossary/Semantics)\n\nWAI-ARIA Roles provide semantic meaning to content, allowing screen readers and other tools to present and support interaction with an object in a way that is consistent with user expectations of that type of object.\nMore detials – [Here](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-hidden)\n\n### Synchrony \u0026 Asynchrony\n\n- **Synchrony** is a term we use to talk about code instructions that execute one after another.\n- **Asynchrony**  doesn't wait for the previous instruction to finish.\n\n**Synchronous code:**\n\n```javascript\nconst arr = [1, 2, 3, 4, 5]\n\nfunction callback(num) {\n console.log(num * 2)\n}\nconst newArray = arr.map(callback)\nconsole.log(\"This code is synchronous.\")\n```\n\n**Console output:**\n\n```bash\n2\n4\n6\n8\n10\nThis code is synchronous.\n```\n\n**Asynchronous code:**\n\n```javascript\nfunction callbackFunc() {\n console.log(\"Executed last because we're using asynchronous code.\")\n}\nsetTimeout(callbackFunc, 1500)\nconsole.log('Executed first')\nconsole.log('Executed second')\n```\n\n**Console output:**\n\n```bash\nExecuted first\nThe string reversed is: \"alone\"\nExecuted last because we're using asynchronous code.\n```\n\n**Traditional Promise**\n\n```javascript\nlet beverages = ['tea', 'coffee', 'apple cider']\n\nfunction pickRandomBeverage() {\n return new Promise(function(resolve, reject) {\n  let randomIndex = Math.floor(Math.random() * beverages.length)\n  let selectedBeverage = beverages[randomIndex]\n  setTimeout(function() {\n   console.log(`${selectedBeverage} selected`)\n   resolve(selectedBeverage)\n  }, 1000)\n })\n}\n\nfunction checkIfHotWaterIsReady(isBeverageSelected) {\n return new Promise(function(resolve, reject) {\n  setTimeout(function() {\n   if (isBeverageSelected) {\n    console.log(\"Preparing...\")\n    resolve(isBeverageSelected)\n   } else {\n    reject(\"No beverage has been picked up.\")\n   }\n  }, 1000)\n })\n}\n\nfunction prepareDrink(selectedBeverage) {\n return new Promise(function(resolve, reject) {\n  setTimeout(function() {\n   if (selectedBeverage) {\n    console.log(`Enjoy your ${selectedBeverage} !`)\n    resolve(true)\n   } else {\n    reject(\"Drink not ready yet...\")\n   }\n  }, 1000)\n })\n}\n\nfunction nativePromiseHandling() {\n const pickedDrink = pickRandomBeverage()\n const handleWaterReadyCheck = function(selectedBeverage) {\n  return checkIfHotWaterIsReady(selectedBeverage)\n }\n const handlePrepareDrink = function(isBeverageSelected) {\n  return prepareDrink(isBeverageSelected)\n }\n pickedDrink\n  .then(\nhandleWaterReadyCheck\n)\n  .then(\nhandlePrepareDrink\n)\n}\nnativePromiseHandling()\n```\n\n**Console output:**\n\n```bash\napple cider selected\nPreparing...\nEnjoy your apple cider !\n```\n\n**async \u0026 await**\n\nThe `async/await` syntax allows us to have more readable code and is usually shorter than a traditional promise.\n\n```javascript\nlet beverages = ['tea', 'coffee', 'apple cider']\n\nfunction pickRandomBeverage() {\n return new Promise(function(resolve, reject) {\n  let randomIndex = Math.floor(Math.random() * beverages.length)\n  let selectedBeverage = beverages[randomIndex]\n  setTimeout(function() {\n   console.log(`${selectedBeverage} selected`)\n   resolve(selectedBeverage)\n  }, 1000)\n })\n}\n\nfunction checkIfHotWaterIsReady(isBeverageSelected) {\n return new Promise(function(resolve, reject) {\n  setTimeout(function() {\n   if (isBeverageSelected) {\n    console.log(\"Preparing...\")\n    resolve(isBeverageSelected)\n   } else {\n    reject(\"No beverage has been picked up.\")\n   }\n  }, 1000)\n })\n}\n\nfunction prepareDrink(selectedBeverage) {\n return new Promise(function(resolve, reject) {\n  setTimeout(function() {\n   if (selectedBeverage) {\n    console.log(`Enjoy your ${selectedBeverage} !`)\n    resolve(true)\n   } else {\n    reject(\"Drink not ready yet...\")\n   }\n  }, 1000)\n })\n}\n\nasync\n function asyncAwaitPromiseHandling() {\n const pickedDrink = \nawait\n pickRandomBeverage()\n const isHotWaterReady = \nawait\n checkIfHotWaterIsReady(pickedDrink)\n const isDrinkPrepared = \nawait\n prepareDrink(isHotWaterReady)\n return isDrinkPrepared\n}\n\nasyncAwaitPromiseHandling()\n```\n\n**Console output:**\n\n```bash\napple cider selected\nPreparing...\nEnjoy your apple cider !\n```\n\n**Try-Catch**\n\nTo handle rejections, we use the `try-catch` syntax.\n\n```javascript\nconst stock = {\n sunglasses: {quantity: 0, price: 29.99},\n bags: {quantity: 2, price: 109.99}\n}\n\nconst purchasePromise = new Promise(function(resolve, reject) {\n if (stock.sunglasses.quantity \u003e 0) {\n  resolve(\"Sunglasses are available. Proceeding with order now.\")\n } else {\n  reject(\"Sunglasses are out of stock. Canceling Order.\")\n }\n})\n\nasync function orderSunglasses() {\n \ntry\n {\n  let result = await purchasePromise\n  console.log(result)\n } \ncatch\n(error) {\n  console.log(error)\n }\n}\n\norderSunglasses()\n```\n\n**Console output:**\n\n```bash\nSunglasses are out of stock. Canceling Order.\n```\n\n### Classes\n\n```javascript\nclass Person {\n  constructor(name, age) {\n    this.name = name\n    this.age = age\n  }\n\n  // Method\n  greet() {\n    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`)\n  }\n}\n\n// Creating an instance of Person\nconst person1 = new Person('Alice', 30)\nperson1.greet() // Output: Hello, my name is Alice and I am 30 years old.\n\nclass Employee extends Person {\n  constructor(name, age, jobTitle) {\n    super(name, age) // Call the parent class constructor\n    this.jobTitle = jobTitle\n  }\n\n  // Overriding the greet method\n  greet() {\n    console.log(`Hello, my name is ${this.name}, I am ${this.age} years old and I work as a ${this.jobTitle}.`)\n  }\n}\n\nconst employee1 = new Employee('Bob', 25, 'Software Engineer')\nemployee1.greet() // Output: Hello, my name is Bob, I am 25 years old and I work as a Software Engineer.\n```\n\n## TypeScript Cheat Sheet\n\n### Basics\n\n**Static Types**\n\nTypeScript define type **annotation** of the variable. (static type)\n\n```typescript\nlet greeting: string = \"Hello, world!\"\ngreeting = 42 // Error\n```\n\n**Type Annotations**\n\n```typescript\nlet distance: number = 45\nlet isCompleted: boolean = true\nlet anything: any = \"I can be anything\"\n```\n\nIf we create a variable without a type, TypeScript infers the type based on the value assigned to it. This is called **type inference**.\n\n```typescript\nlet price = 100; // number\nprice = \"expensive\" // Error\n```\n\n**Union Types**\n\nUnion types allow us to allow multiple types for one variable. The variable can be one value or another.\n\n```typescript\nlet variable: number | string\nlet variable: number | string | boolean\n```\n\n**Arrays**\n\nWe add an opening and closing square bracket right after the type to indicate that this variable will hold an array of the given type.\n\n```typescript\nlet numArray: number[]\nlet stuff: (number | string)[]\n```\n\n**Objects**\n\nWe define the attributes inside the object as we have defined types before. Start with the name, followed by a colon and its type.\n\n```typescript\nlet person: {\n    name: string,\n    age: number\n}\n\nperson = {\n    name: \"John\",\n    age: 25\n}\n\nlet player: {\n    name: string,\n    scores: number[]\n} = {\n    name: \"Lee\",\n    scores: [1, 2, 3]\n}\n```\n\n### More Types\n\n**Type Aliases**\n\nWe use **type aliases** to give types a name, making code clearer and safer. We define **type aliases** using the `type` keyword.\n\n```typescript\n\ntype Human = {\n    name: string,\n    age: number\n}\n\nlet jacky: Human = {\n    name: \"Jacky\",\n    age: 63\n}\n\ntype PriceSeries = number[]\nconst stockOrices: PriceSeries = [108, 103, 110]\n\ntype UserID = number | string\nlet id: UserID = '#251120'\n```\n\n**Intersection Types**\n\nIntersection types in TypeScript allow you to combine multiple types into a single type. A variable of an intersection type must satisfy all the combined types.\n\n```typescript\ntype Person = {\n    name: string\n}\n\ntype Employee = {\n    employeeId: number\n}\n\ntype PersonEmployee = Person \u0026 Employee\n\nlet person: PersonEmployee = {\n    name: \"Miriam\",\n    employeeId: 5\n}\n```\n\n**Interfaces**\n\nInterfaces work similarly to type annotations in TypeScript, allowing you to define custom types for objects and enforce type safety.\n\n```typescript\ninterface Person {\n    name: string\n}\n\nlet person: Person = {\n    name: \"Lisa\"\n}\n\ninterface Animal {\n    species: string\n}\n\ninterface Animal extends Animal {\n    name: string\n}\n```\n\n**Special Properties**\n\nOptional properties are not required in the objects that implement the interface. We mark a property as optional with a question mark `?`.\n\n```typescript\ninterface Person {\n    firstName: string,\n    lastname: string,\n    middleName?: string\n}\n\nlet phurin: Person = {  // No error\n    firstName: \"Phurin\",\n    lastname: \"Nararat\"\n}\n```\n\nIn TypeScript, `readonly` properties prevent modifications after initialization, keeping their values constant.\n\n```typescript\ntype Character = {\n    readonly id: number,\n    name: string\n}\n\nlet anna: Character = {\n    id: 1,\n    name: \"Anna\"\n}\n\nanna.id = 2 // Error\n```\n\nJust like multiple attributes can be marked as optional in an object type.\n\n```typescript\ntype Food = {\n    type: string,\n    brand: string?,\n    color: string?\n}\n```\n\n### Functions, Classes, \u0026 Enums\n\n**Functions**\n\nJust like in JavaScript, we define a function in TypeScript using the `function` keyword. One difference is that we can and should define the function's return type. We use `void` to indicate no return at all. When using parameters in TypeScript, we also need to specify the type of the arguments we use.\n\n```typescript\n\nfunction greet(name: string): void {\n    console.log(\"Hello, \" + name)\n}\n\nfunction sum(a:number, b: number): number {\n    return a + b\n}\n\nfunction sumArray(numbers: number[]): number {\n    return numbers.reduce((sum, num) =\u003e sum + num, 0)\n}\n```\n\n**Function Types \u0026 Signature**\n\nWe can also declare that a variable can hold a function. We do this with the `Function` type annotation.\n\n```typescript\nlet myFirstFunction: Function\nmyFirstFunction = function(a: number, b: number): number {\n    return a + b\n}\n```\n\nIf we use the `Function` type annotation, we know that this variable will hold some kind of function, but we don’t know the details. We can then assign any function. This is not very type-safe as we don't define the parameters or return type.\n\nWe can be more specific about the function parameters and return type. We use arrow function syntax to create a *function signature*.\n\n```typescript\nlet mySecondFunction: (x: number, y: number) =\u003e number\nmySecondFunction = function(x: number, y: number): number {\n    return x + y\n}\n\nlet result = mySecondFunction(5, 10)\n```\n\nType aliases can clarify certain coding patterns, like callbacks. Let's use a type alias for our signature to give it a name like `Callback`.\n\n```typescript\ntype Callback = (data: string) =\u003e void\n\nfunction processString(input: string, callback: Callback): void {\n    const processed = input.toUpperCase()\n    callback(processed)\n}\n\nconst logResult: Callback = (data: string) =\u003e {\n    console.log(data)\n}\n\nprocessString(\"I'm hungry!\", logResult)\n```\n\n**Optinal \u0026 Default Parameter**\n\nIn TypeScript, we can make an argument of a function optional by appending a question mark `?` to the parameter name.\n\n```typescript\nfunction greet(name: string, age?: number): void {\n    if (age !== undefined) {\n        console.log(`Hello ${name}, you are ${age} years old.`)\n    } else {\n        console.log(`Hello ${name} - age not specified.`)\n    }\n}\n\ngreet(\"Maria\") // No error\ngreet(\"Maria\", 41)\n```\n\nIf we want to provide a default value for an argument, TypeScript has us covered with default parameters!\n\n```typescript\nfunction calculateToPrice(price: number, texRate: number = 0.05): number {\n    return price + (price * taxRate)\n}\n\nfunction calculateArea(width: number, height: number = width): number {\n    return width * height\n}\n```\n\n**Classes**\n\nSimilar to classes in JavaScript, we define them using the `class` keyword. There's no difference to JavaScript when adding a constructor to the class. But when we pass parameters to a constructor we need to specify the parameter's type. And when we define a class parameter, we also want to specify its type.\n\n```typescript\nclass Person {\n    name:string\n    constructor(name: string){\n        this.name = name\n    }\n}\n```\n\nIn JavaScript, all properties are accessible from the outside. \n- The `public` keyword in TypeScript makes that explicit. \n- The `private` keyword in TypeScript makes the property or method of a class inaccessible from outside that class.\n- The `protected` keyword in TypeScript prevents a property or method of a class from being accessed outside of that class and its subclasses.\n\n```typescript\nclass Employee {\n    public name: string\n    private id: number\n    protected department: string\n    gender: string\n    constructor(name: string, id: number, department: string, public gender: string) {\n        this.name = name\n        this.id = id\n        this.department = department\n        this.gender = gender\n    }\n}\n\nconst employee = new Employee(\"Phurin\", 1234, \"Engineer\", \"Male\")\nconsole.log(employee.name) // No error\nconsole.log(employee.id) // Error\n```\n\n**Enums**\n\nEnums or enumerations give more friendly names to a set of named constants. We start with the keyword `enum`. Then we need a name for the enum as well as open and closed braces. Finally, we add the values inside the braces, separated by a comma.\n\nIn TypeScript, each member of enum is automatically assigned a number starting from 0, automatically.\n\n```typescript\nenum Directions {\n    Up,\n    Down,\n    Left,\n    Right\n}\n\nconsole.log(Directions.Up) // 0\n```\n\nWe can manually set the value of enum members. We only need to do this with the first one, and the others are incremented automatically.\n\n```typescript\nenum Directions {\n    Up = 5,\n    Down,\n    Left,\n    Right\n}\n\nconsole.log(Directions.Up) //5\nconsole.log(Directions.Down) //6\nconsole.log(Directions.Left) //7\nconsole.log(Directions.Right) //8\n```\n\nIt also works the other way around. Enums in TypeScript are objects. So, you can also get the name of an enum member from its value.\n\n```typescript\nenum Directions {\n    Up = 1,\n    Down,\n    Left,\n    Right\n}\n\nconsole.log(Directions[1]) // Up\n```\n\nWe can also use string values instead of auto-incrementing numbers.\n\n```typescript\nenum MusicGenres {\n    Classical = \"CLASSICAL\",\n    Rock = \"ROCK\",\n    Pop = \"Pop\",\n    Jazz = \"Jazz\"\n}\n\nconsole.log(MusicGenres.Classical) // CLASSICAL\n\n```\n\nA single enum can store both numbers and strings.\n\n```typescript\nenum Options {\n    Yes = 1,\n    No = \"No\"\n}\n```\n\n### Generics\n\nGenerics allow us to write flexible, reusable code that can work with any data type while maintaining type safety. They allow us to create code that can work with various types without sacrificing the benefits of strong typing.\n\nlet's look at a simple function that finds the biggest number in an array.\n\n```typescript\nfunction findMaxNumber(array: number[]): number {\n    return array.reduce((max, item) =\u003e (item \u003e max ? item : max))\n}\n\nconst maxNumber = findMaxNumber([1, 3, 2])\nconsole.log(maxNumber)\n```\n\nIf we want to do the same with strings where we look for the maximum value alphabetically, we could define another function.\n\n```typescript\nfunction findMaxNumber(array: number[]): number {\n    return array.reduce((max, item) =\u003e (item \u003e max ? item : max))\n}\n\nconst maxNumber = findMaxNumber([1, 3, 2])\nconsole.log(maxNumber)\n\nfunction findMaxString(array: string[]): string {\n    return array.reduce((max, item) =\u003e (item \u003e max ? item : max))\n}\nconst maxString = findMaxString([\"a\", \"b\", \"c\"])\nconsole.log(maxString)\n```\n\nInstead of defining the function twice, we can use generics to allow any type later. For now, we use `T` as a placeholder for any type. After declaring the generic type, we can call it with any type.\n\n```typescript\nfunction findMax\u003cT\u003e(array: T[]): T {\n    return array.reduce((max, item) =\u003e (item \u003e max ? item : max))\n}\n\nconst maxNumber = findMax\u003cnumber\u003e([1, 3, 2])\nconsole.log(maxNumber)\n\nconst maxString = findMax\u003cstring\u003e([\"a\", \"b\", \"c\"])\nconsole.log(maxString)\n```\n\nWe can also use generics when creating a class. We define the generic class with `\u003cT\u003e` that we then can use throughout the class. And we also can leave the type specification for the generic out as TypeScript can infer it.\n\n```typescript\nclass Container\u003cT\u003e {\n    constructor(public value: T) {}\n}\n\nlet numberContainer = new Container\u003cnumber\u003e(42)\nlet stringContainer = new Container\u003cstring\u003e(\"Hello\")\nlet booleanContainer = new Container(true)\n```\n\nAs you know, we can also define an array of strings. This also works with the generic way of defining array types. We can also create interfaces with a generic type. The initial syntax looks similar to classes with generics that we've seen before.\n\n```typescript\nlet names: Array\u003cstring\u003e = [\"Hello\", \"TypeScript\"]\n\nclass BoxClass\u003cT\u003e {\n    contents: T\n}\n\ninterface BoxInterface\u003cT\u003e {\n    contents: T\n}\n```\n\n## React Cheat Sheet\n\n### Intro to React\n\nReact is a common JavaScript library to build web apps. A package manager like `npm` will allow you to set up React on your computer.`npm install react`\n\n```javascript\nimport React from 'react'           // gain access to React's various features\nimport ReactDOM from 'react-dom'    // allow you to render your content onto a webpage\n\nReactDOM.render(                    // render content into webpage\n    \u003ch1\u003eHello, world\u003c/h1\u003e,          // element that will added to destination\n    document.getElementById(\"root\") // destination element\n```\n\n### JSX\n\n`JSX` (JavaScript XML) is a markup syntax that combines User Interface (UI) elements and logic. Basically, `JSX` tells the browser what to render and how.\n\nNoticed in `index.html` that the `src` attribute loads the `JSX` file with `index.js`.\n\nThis is because `JSX` is just fancy JavaScript code. `React` recognizes both `.jsx` and `.js` files the same.\n\n```html\n\u003c!doctype html\u003e\n\u003chtml\u003e\n \u003chead\u003e\n \u003c/head\u003e\n \u003cbody\u003e\n  \u003cdiv id=\"root\"\u003e\u003c/div\u003e\n  \u003cscript type=\"module\" src=\"./index.js\"\u003e\u003c/script\u003e\n \u003c/body\u003e\n\u003c/html\u003e\n```\n\n`JSX` code allows us to generate `HTML` tags, hence why we can add HTML-like code inside JavaScript.\n\n```javascript\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\n\nconst header = (\n \u003ch1\u003e\n  Hello, Lori Smith\n \u003c/h1\u003e\n)\n\nReactDOM.render(\n    header,\n    document.getElementById(\"root\")\n)\n```\n\nWe can also use `variables` to insert `JSX` into other elements. We do that with the help of embedded expressions.\n\n```javascript\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\n\nconst header = \u003ch1\u003eHello, John\u003c/h1\u003e\nconst subheader = \u003ch2\u003eThe movie\u003c/h2\u003e\n\nconst app = (\n    \u003cdiv\u003e\n        {header}\n        \u003cp\u003e{\"My name is Phurin Nararat. :)\"}\u003c/p\u003e\n        {subheader}\n    \u003c/div\u003e\n)\n\nReactDOM.render(\n    app,\n    document.getElementById(\"root\")\n)\n```\n\n### Class Components\n\nReact applications are built using building blocks called components, which represent different parts of an app's user interface (UI). There are two types of components in React: **Functional Components** and **Class Components**.\n\n**Class Components** were the primary way of creating components until the introduction of `hooks` in `React 16.8`. They offered additional features such as `state`, which allowed components to hold and manage data that can change over time.\n\n\n**Class Components** are built with classes, templates for objects that hold onto information that can change over time.\n\n```javascript\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\n\nclass App extends React.Component {\n    // to pass variable to class component, we need to overide `constructor` of the class and pass `props` to `super` method\n    constructor(props) {\n        super(props)\n        this.state = {count: 0}   // `state` hold information overtime\n    }\n    \n    // component-specific function that is called after a component loads\n    componentDidMount() {\n\n        // use `this.setState` to update values\n        this.setState({count:1})\n    }\n    \n    // after overided `contructor`, we can use passed variable via `props` \n    render() {\n        const welcome = this.props.name\n        return (\n            \u003cdiv\u003e\n                \u003ch1\u003e{welcome}\u003c/h1\u003e\n                \u003cp\u003eWelcome to my first React component!\u003c/p\u003e\n                \u003cp\u003eOur count is currently {this.state.count}.\u003c/p\u003e\n            \u003c/div\u003e\n        )\n    }\n}\n\nReactDOM.render(\n    // pass my name to the component\n    \u003cApp name=\"Phurin Nararat\" /\u003e,\n    document.getElementById(\"root\")\n)\n```\n\nLike with JavaScript, React event handlers, update methods can access event information through their first argument, usually named `event` or `e`.\n\n```javascript\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\n\nclass App extends React.Component {\n    constructor(props) {\n        super(props)\n        this.state = { text:\"\" }\n    }\n\n    handleInput = (event) =\u003e {\n        const val = event.target.value\n        this.setState({text:val})\n    }\n\n    render() {\n        return (\n            \u003cdiv\u003e\n                \u003ch1\u003eHello, {this.props.name}\u003c/h1\u003e\n                \u003cinput \n                type=\"text\" \n                placeholder=\"Type Here\"\n                value={this.state.text}\n                onChange={this.handleInput}\n                /\u003e\n                \u003cp\u003e\u003cstrong\u003eYour entry is:\u003c/strong\u003e{this.state.text}\u003c/p\u003e\n            \u003c/div\u003e\n        )\n    }\n}\n\nReactDOM.render(\n    \u003cApp name=\"Phurin Nararat\" /\u003e,\n    document.getElementById(\"root\")\n)\n```\n\n### Functional Components\n\n**Functional components** are special functions that return `JSX`. We can write functional components with the normal `function()` syntax or the ES6 arrow function `() =\u003e {}` syntax.\n\n```javascript\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\n\nconst App = (props) =\u003e {\n    // functional component can pass `props` directly as argument\n    const name = props.name\n    \n    return (\n        \u003cdiv\u003e\n            \u003ch1\u003eWelcome, {name}\u003c/h1\u003e\n        \u003c/div\u003e\n    )\n}\n\nReactDOM.render(\n    \u003cApp name=\"Phurin Nararat\" /\u003e,\n    document.getElementById(\"root\")\n)\n```\n\n### CSS Styling in React\n\nWe can create object to style in React or by import `css` style by `import \"./App.css\"` at the top of code.\n\n```javascript\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\n\nconst App = () =\u003e {\n    const styles = {\n    header:{\n        textDecoration: \"underline\"\n    },\n    paragraph:{\n        color: \"blue\",\n        fontWeight: \"bold\"\n    }\n}\n\n    return (\n        \u003cdiv\u003e\n            \u003ch1 style={styles.header}\u003eStyling in React\u003c/h1\u003e\n            \u003cp style={styles.paragraph}\u003eThis is blue-colored text.\u003c/p\u003e\n        \u003c/div\u003e\n    )\n}\n\nReactDOM.render(\n \u003cApp /\u003e,\n document.getElementById('root')\n)\n```\n\n### Hooks and useState\n\nAs arrival of `React` Hooks (`React 16.8`), `functional components` can have state in React. Hooks offer many benefits such as simplifying code, removing `this`, and separating JavaScript logic from the UI. Additionally, rather than rewriting functional components into class components when we need `state`, we can simply use `useState`.\n\n```javascript\nimport React, { useState } from \"react\"\nimport ReactDOM from \"react-dom\"\n\nconst App = () =\u003e {\n    const [username, updateUsername] = updateCount(\"\")\n\n    return (\n        \u003cdiv\u003e\n            \u003ch1\u003eEnter a username\u003c/h1\u003e\n            \u003cp\u003ePlease, let me know the username you wish to use:\u003c/p\u003e\n            \u003cinput type=\"text\" value={count + 1}  \n            onChange={(e) =\u003e (e.target.value)}\n            /\u003e\n        \u003c/div\u003e\n    )\n}\n\nReactDOM.render(\n \u003cApp /\u003e,\n document.getElementById(\"root\")\n)\n```\n\n### Hooks and useEffect\n\n`useEffect` is a hook that is automatically called every time the component renders. It requires a function as its first argument. The method we passed to `useEffect` contains the code the component will run every time it renders.\n\nIf `useEffect` updates `useState` variables, it's possible to run infinitely looping code and hamper our app's performance.\n\nOne way to prevent this is to add conditional checks in `useEffect`\n\n```javascript\nimport React, {useState, useEffect} from \"react\"\nimport ReactDOM from \"react-dom\"\n\nconst App = () =\u003e {\n    const [first, setFirst] = useState(\"\")\n    const [second, setSecond] = useState(\"\")\n    const [multiplication, setMultiplication] = useState(null)\n\n    useEffect( ()=\u003e{\n        if(multiplication == null) setMultiplication(first * second)\n    })\n\n    return (\n        \u003cdiv\u003e\n            \u003ch1\u003eMultiply\u003c/h1\u003e\n            \u003cp\u003eThe answer is: {multiplication}!\u003c/p\u003e\n            \u003cp\u003eNumbers to multiply:\u003c/p\u003e\n            \u003cinput \n            type=\"number\" \n            value={first} \n            onChange={(e)=\u003e{\n                setFirst(e.target.value)\n                setMultiplication(null)\n            }}\n        /\u003e\n        \u003cinput \n        type=\"number\" \n        value={second} \n        onChange={(e)=\u003e{\n            setSecond(e.target.value)\n            setMultiplication(null)\n            }}\n        /\u003e\n        \u003c/div\u003e\n    )\n}\n\nReactDOM.render(\n    \u003cApp /\u003e,\n    document.getElementById(\"root\")\n)\n```\n\nDependency `[]` arrays prevent unnecessary `useEffect` calls and also reduce the possibility of infinite loops.\n\n```javascript\nuseEfefct(() =\u003e {}, []) // we can define dependency in `[]` such as `[a, b]` while `a` and `b` is variable\n```\n\n`useEffect()` might cause memory leaks if we end up removing a component without calling a cleanup method. If `useEffect()` contains timers or API calls, it's good practice to `return` a cleanup method to end those processes when not needed.\n\n```javascript\nimport React, { useState, useEffect } from \"react\"\n\nconst Timer = () =\u003e {\n    const [ time, setTime ] = useState(0)\n\n    useEffect(()=\u003e{\n        const interval = setInterval(()=\u003e{\n            const d = new Date()\n            setTime(d.toLocaleTimeString())\n        },100)\n        return () =\u003e {\n            clearInterval(interval)\n        }\n    },[])\n\n    return (\n        \u003cdiv className=\"centered\"\u003e\n            \u003ch1\u003eYour current time:\u003c/h1\u003e\n            \u003ch3\u003e{time}\u003c/h3\u003e\n        \u003c/div\u003e\n    )\n}\n\nexport default Timer\n```\n\n### Conditional Rendering\n\n`if/else` statements are commonly used in React to introduce JavaScript logic into `JSX`, controlling what is rendered based on some condition.\n\n```javascript\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\n\nconst App = () =\u003e {\n    const number = 48\n    let response\n    if(number % 2 === 1) {\n        response = \u003cp\u003eThis is an odd number.\u003c/p\u003e\n    } else {\n        response = \u003cp\u003eThis is an even number.\u003c/p\u003e\n    }\n    return response\n}\n\nReactDOM.render(\u003cApp /\u003e, document.getElementById(\"root\"))\n```\n\n### Ternary Operators and \u0026\u0026\n\nJavaScript offers different ways to write conditional statements, which we can then also use in React. One identifiable difference is that instead of `if` and `else`, they use `?` and `:` respectively. `(\u003ccondition\u003e) ? \u003cyes\u003e:\u003cno\u003e`\n\n```javascript\nconst number = 101\nconst toPrint = (number % 2 == 1) \n?\"This is an odd number.\" \n:\"This is an even number.\"\nconsole.log(toPrint)\n```\n\n**Console output:**\n```bash\nThis is an odd number.\n```\n\nAnother way to write conditionals is the `\u0026\u0026` operator. Normally, we use it in `if` statements to test two conditions simultaneously.\n\n```javascript\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\n\nconst App = (props) =\u003e {\n    return (\n        \u003cdiv\u003e\n            \u003ch2\u003eCloth, Sink, and Below - Household Appliances\u003c/h2\u003e\n            {\n                props.loggedIn \u0026\u0026 \u003cp\u003eWelcome, dear customer!\u003c/p\u003e\n            }\n        \u003c/div\u003e\n    )\n}\n\nReactDOM.render(\n \u003cApp loggedIn={true} /\u003e,\n document.getElementById(\"root\")\n)\n```\n\n### Lists and Maps\n\n```javascript\nconst items = [\n    \"First Item\",\n    \"Second Item\",\n    \"Third Item\"\n]\n\nconst listItems = items.map(message =\u003e {\n    return \u003cp\u003e{message}\u003c/p\u003e\n    })\n```\n\nUsing an item’s array `index` as the `key` is not recommended. If the array order changes, we will end up using the wrong item. If an array item comes with an `id` or other unique identifiers, we can use that as the `key` instead.\n\n```javascript\nimport React, {useState} from \"react\"\nimport ReactDOM from \"react-dom\"\n\nconst App = () =\u003e {\n    const [tasks] = useState([\n        {\n            tasks.map:1,\n            task:\"Get the groceries\"\n        },\n        {},\n        {\n            tasls.map:2\n            task:\"Complete my homework\"\n        }\n    ])\n\n    return (\n        \u003cul\u003e\n            {\n                tasks.map(item =\u003e {\n                    return \u003cli key={item.tasks.map}\u003e{item.task}\u003c/li\u003e\n                })\n            }\n        \u003c/ul\u003e\n  )\n}\n\nReactDOM.render(\n \u003cApp /\u003e,\n document.getElementById(\"root\")\n)\n```\n\n## SQL Cheat Sheet\n\n```sql\nSELECT * FROM table_name\nSELECT column1 AS alias1, column2 FROM table_name\nSELECT DISTINCT column1, column2 FROM table_name\nSELECT * FROM table_name ORDER BY column1       -- Ascending by default\nSELECT * FROM table_name ORDER BY column1 ASC   -- Least -\u003e Most\nSELECT * FROM table_name ORDER BY column1 DESC  -- Most -\u003e Least\nSELECT * FROM table_name WHERE column1 = value1 AND (column2 != value1 OR column2 != value2) -- =, !=, \u003c\u003e, \u003c, \u003e, \u003c=, \u003e=, AND, OR, NOT\n\nINSERT INTO orders(column1, column2, column3) VALUES(value1, value2, vaue3)\nUPDATE table_name SET column1 = value1 WHERE column2 = value2\nDELETE FROM table_name WHERE column1 = value1\n\nCREATE TABLE table_name (\n  column1 datatype1,\n  column2 datatype2,\n  column3 datatype3\n)\n\n-- Use `ALTER` follow by the opearation to change existing table directly\nALTER TABLE table_name ADD column4 datatype4 -- Add column to existing table without data\nALTER TABLE table_name DROP COLUMN column4 -- Remove column from existing table\nALTER TABLE table_name RENAME column3 TO newColumn3\n\nSELECT * FROM table_name WHERE column1 BETWEEN value1 AND value2\n\n-- `%` call wildcard, it used for pattern conditioning\n-- wildcard can use as '%a%', '%a', 'a%' or without wildcard like 'a'\nSELECT * FROM table_name WHERE column1 LIKE 'a%' -- Condition by pattern like `table_name` with a `column1` starting with a\n\nSELECT * FROM table_name WHERE column1 IN (value1, value2, ..., value4)\n\n-- Aggregate function MIN, MAX, SUM, AVG, COUNT\nSELECT SUM(column1) FROM table_name\nSELECT SUM(column1) FROM table_name GROUP BY column2\nSELECT column1 FROM table_name GROUP BY column2 HAVING column3 -- Select column1 group by column2 but column 1 must have column3 in result\n\n-- JOIN TABLE\n-- `LEFT JOIN` select all row from left table and include matching row from right table\nSELECT * FROM table_name1\nLEFT JOIN table_name2\nON table_name1.column_name =\ntable_name2.column_name\n-- `RIGHT JOIN` select all row from right table and include matching row from left table\nSELECT * FROM table_name1\nRIGHT JOIN table_name2\nON table_name1.column_name =\ntable_name2.column_name\n-- `FULL OUTER JOIN` is combination of `LEFT JOIN` and `RIGHT JOIN`. It include both left and right table.\nSELECT * FROM table_name1\nFULL OUTER JOIN table_name2\nON table_name1.column_name =\ntable_name2.column_name\n\n-- Sub queries is nested queries, this can use together with another table\nSELECT * FROM table_name WHERE column2 \u003e (\n  SELECT AVG(column1) FROM table_name\n)\nSELECT * FROM table_name WHERE column2 IN (\n  SELECT column1 FROM table_name\n)\n```\n\n## Node.js Cheat Sheet\n\n### Intro to Node.js\n\nNode.js is an open-source runtime environment that enables developers to create full-stack applications using only JavaScript.\n\nFull-stack applications involve the code that runs in the browser and also the code that runs on the server.\n\nEverything we've done until now focuses on code that runs in the browser, which is called the frontend or client-side.\n\nThe frontend receives code sent from a server connected to the internet. We call that the backend or server-side.\n\nFor now, we'll only concentrate on utilizing Node.js to support frontend development.\n\nNode.js enables developers to import libraries and other modules into a project without using a separate `script` tag in the HTML.\n\nJavaScript has numerous libraries that assist in the development of applications.\n\nThese libraries are typically organized and distributed in packages. We can handle these packages with a package manager.\n\n```bash\nnpm install moment\n```\n\nTo create a project using Node we must initialize the project.\n\nA project can be created using the command `npm init` in the terminal.\n\n```bash\nnpm init react-app \u003capp name\u003e\n```\n\nTo install packages, type `npm install` or `npm i` followed by the package name.\n\nInstalling a package updates the package.json file, which displays a list of all installed packages in the project.\n\n```json\n{\n  \"name\": \"my-app\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"dependencies\": {\n    \"@testing-library/jest-dom\": \"^5.16.5\",\n    \"@testing-library/react\": \"^13.4.0\",\n    \"@testing-library/user-event\": \"^13.5.0\",\n    \"react\": \"^18.2.0\",\n    \"react-dom\": \"^18.2.0\",\n    \"react-router-dom\": \"^6.8.2\",\n    \"react-scripts\": \"5.0.1\",\n    \"web-vitals\": \"^2.1.4\"\n  }\n}\n\n```\n### Client vs Servers\n\n**Introduction**\nMost complex websites use server-side programming to create dynamic content.\n\nThis means writing code that runs on another computer functioning as a server, using a database to store and retrieve information.\n\nLogin pages like the one below are almost always created with the help of server-side code.\n\nHTTP stands for **HyperText Transfer Protocol**. It's how the browser communicates with the server when you click on a URL link.\n\nThe browser makes a **request** to the server, and the server sends back a **response**. This is how browser and server communication works.\n\n```bash\n              Request\n┌─────────┐               ┌─────────┐\n│ Browser │ ────────────► │ Server  │\n└─────────┘               └─────────┘\n              Response\n┌─────────┐               ┌─────────┐\n│ Browser │ ◄──────────── │ Server  │\n└─────────┘               └─────────┘\n```\n\n**Frontend and Backend Tasks**\n\nCode running the browser is called client-side, or frontend. It also handles interactivity on a page, like hiding or showing an element. Client-side code is written in HTML, CSS, and Javascript.\n\nServer-side code handles the specifics of what content is sent to the browser.\n\n```javascript\nconst express = require(\"express\")\nconst bodyParser = require(\"body-parser\")\nconst db = require('./queries')\nconst app = express()\n\napp.use(\n    bodyParser.urlencoded({\n        extended: true\n    })\n)\n\napp.get('/robot', db.getRobots)\napp.get('/robot/:id', db.getRobotsId)\napp.post('/robot', db.createRobot)\napp.listen(3000)\n```\n\nJavaScript is one of the languages that we can use to write both frontend and backend code.\n\n**Static and Dynamic**\n\nWebsites that always show the same data are **static websites**. These don't use a server to display dynamically generated content.\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003cbody\u003e\n    \u003ch2\u003eAbout us\u003c/h2\u003e\n    \u003cp\u003eWe're a family business specializing in giving you the most authentic neapolitan pizza experience!\u003c/p\u003e\n\u003c/body\u003e\n```\n\nDynamic websites generate some of their content dynamically, by requesting data from the server and displaying the response. Clients request the content stored in servers' databases. Then, clients update the HTML they display, filling in the new content.\n\nSo we don't need to write individual HTML files for each piece of information\n\nUsing a database and server-side code means we only need to create one HTML template that we can use for every item in the catalog.\n\nDynamic websites can return **different content** for a request based on information in the URL or other information stored in the browser.\n\n```url\nhttps://catalog.com/api/products?results=10 // dispaly 10 result\n```\n\n### Communicating with an API\n\n**What is an API?**\n\nApplication programming interfaces, also known as `API`, facilitate communication between two programs.\n\n`APIs` send requests from a sender program to a receiver program. Then, they send responses from the receiver to the sender program.\n\nMany things in our daily life work like an `API`. One example is a waiter and the kitchen staff.\n\nA waiter, like a sender program, sends an order to the kitchen. Then the kitchen, as a receiver program, sends back the food as a response.\n\n**Why use an API?**\n\nBack-end developers don't need to wait for front-end development to be completed to test their program.\n\nThey can test their program by simply sending requests to the `API` and checking if the responses are correct.\n\n\n**fetch and API tools**\n\nWe can send requests to `APIs` using `fetch()` in JavaScript.\n\n```javascript\nfetch(url, method: \u003c'GET', 'PUT', 'PATCH', 'DELETE'\u003e, body: \u003c'body'\u003e).then(callback)\n```\n\n### HTTP Requests\n\n**Request Line and parameters**\n\nA request is made of different parts, each with a specific role. The **URL** specifies the **location** of the server and the content or **resource**. The **method** of a browser request defines the type of action it should perform. There are a few different methods that browsers can send.\n\n```bash\n GET     https://abc.com    /movies\n|___|   |_______________|  |_______|\nmethod   backend location   resource\n\n```\n\nURLs can have **parameters**, like `1010` here that stands for a user's ID.\n\n```bash\nformat: https://abc.com/users/:id\n\n    GET https://abc.com/users/1010 HTTP/1.1\n```\n\n**Query parameters**\n\nThe request line URL can also have **query parameters**. These are key-value pairs that appear after a `?` sign.\n\n```bash\nGET https://abc.com/users?membership=regular HTTP/1.1\n```\n\nURLs can have several query parameters chained through `\u0026`. Here, we're requesting premium users with an active streak.\n\n```bash\nGET https://abc.com/users?membership=regular\u0026isactive=true HTTP/1.1\n```\n\nThrough their labeled nature, query parameters like `id=1010` make the URL more understandable.\n\n```bash\nusing query parameters:\nGET https://abc.com/users?id=1010 HTTP/1.1\n\nusing simple parameters:\nGET https://abc.com/users/1010 HTTP/1.1\n```\n\n**Request body**\n\nUnder the request line, a browser request has a series of headers\n\n```bash\nGET https://abc.com/movies HTTP/1.1\nHost: abc.com\nUser-Agent: Mozilla/5.0 \nAccept: text/html,image/jpeg\nAccept-Language: en-us,en\nAccept-Encoding: gzip,deflate\nAccept-Charset: ISO-8859-1,utf-8\nKeep-Alive: 300\nConnection: keep-alive\nCookie: PHPSESSID=r2t5uvjq435r4\nCache-Control: no-cache\n```\n\n### HTTP Request Responses\n\n**Status line**\n\nThe status line contains the protocol `HTTP/1.1` followed by the status code `200 OK`. For more information click – [Here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status)\n\n```bash\nHTTP/1.1 200 OK\nDate: Mon, 27 Jul 2009 12:28:53 GMT\nServer: Apache/2.2.14 (Win32)\nLast-Modified: Wed, 22 Jul 2009 19:15:56 GMT\nContent-Length: 88\nContent-Type: application/json\nConnection: Closed\n\n{\n \"item\": \"jeans\",\n \"price\": 89\n}\n```\n\n**Response Body**\n\nn case of a successful request, the client will get a `200 OK` response code, along with a **response body** containing the data. One common format for an HTTP response body is JSON, which stands for Javascript Object Notation. The JSON syntax is similar to that of a JavaScript object.\n\n```bash\nHTTP/1.1 200 OK\nDate: Mon, 27 Jul 2009 12:28:53 GMT\nServer: Apache/2.2.14 (Win32)\nLast-Modified: Wed, 22 Jul 2009 19:15:56 GMT\nContent-Length: 88\nContent-Type: application/json\nConnection: Closed\n\n{\n  \"username\": \"phurin\",\n  \"name\": \"Phurin Nararat\"\n}\n```\n\n\n## Express.js Cheat Sheet\n\n### Introduction to ExpressJS\n\nWe know the basics about how the frontend and backend communicate. Now we can start building our web server with Express.\n\nRemember, a web server is responsible for storing, managing, and serving files to web browsers when they're requested.\n\nExpress is a popular web framework for Node.js that simplifies the setup, installation, and management of web servers.\n\nIt's also a minimalist package, meaning it doesn't require other libraries or plugins to function.\n\nRecall that Node.js is an open-source runtime environment that enables developers to create full-stack applications using only JavaScript.\n\nFull-stack applications handle both the frontend and backend components of a web application.\n\nTo install Express in our project, we use the `npm install express` command.\n\nTo use Express, we require it in our code using Node's built-in require() function.\n\nWe typically assign the output of require() to a variable with the same name as the package we're using.\n\nThe `listen()` function takes two parameters. The first parameter specifies the **port number**.\n\nThe second parameter is a **callback function** that executes when the server starts.\n\nThe port number is a distinctive identifier that tells the server which application should process an incoming request.\n\nPorts allow multiple applications to connect to a server simultaneously with different HTTP requests.\n\n```javascript\nconst express = require('express')\nconst app = express()\nconst port = 8000\n\napp.listen(port, callback)\n```\n\n### Request and Response Objects\n\n**The Request Object**\n\nExpress' `get()` method defines a specific route that matches incoming HTTP GET requests to a specified path and triggers a callback function.\n\n```javascript\nconst express = require(\"express\")\nconst app = express()\nconst port = 3000\n\napp.get(\"/\", () =\u003e {})\n\napp.listen(port, () =\u003e {\n  console.log(`The server is listening on port ${port}`)\n})\n```\n\nThe callback function accepts two arguments: a request object and a response object. These are often written as `req` and `res`.\n\nAll endpoints require a path and utilize the `req` and `res` objects as parameters in their callback function.\n\n```javascript\napp.get(\"/\", (req, res) =\u003e {console.log(req)})\n```\n\nThe `req` object has properties with useful information that can be used to help manage and respond to requests.\n\nThe `req.method` property for example contains information on the type of HTTP request that was sent. (GET, POST, PUT, PATCH, DELETE)\n\nThe `req.hostname` identifies the device or server making the request. This can be useful in deciding if a request is approved or denied.\n\nParameter values can be useful in a wide variety of situations by allowing the response to be more dynamic based on the request.\n\n```javascript\napp.get(\"/flag/:country\", (req, res) =\u003e {\n  console.log(`New request made: ${req.method}`)\n  console.log(`Country parameter: ${req.params.country}`)\n // use the parameter to retrieve specific flag data\n})\n```\n\n**The Response Object**\n\nThe requesting client needs to know the final status of its request. We use the `status()` method to set the HTTP status code.\n\n```javascript\napp.get(\"/about\", (req, res) =\u003e {\n  console.log(`New request made: ${req.method}`)\n  res.status(200).send(\"\u003cp\u003eSuccessful Request\u003c/p\u003e\")\n})\n```\n\n`redirect()` can redirect the browser to a page's new URL. It's also used when a page's content has been moved to a new location on the page.\n\n```javascript\napp.get(\"/user\", (req, res) =\u003e {\n  console.log(`New request made: ${req.method}`)\n  res.redirect(\"/userinfo\")\n  res.send(\"\u003ch1\u003eUser Info Page\u003c/h1\u003e\")\n})\n```\n\n### ExpressJS Route Parameters\n\nIn Express we use routes to handle incoming requests. A route is a specified URL path and HTTP method.\n\nWhen a request is mapped to a route, the route processes the request and a response is sent.\n\nIn Express the route's path can be a string, a string pattern, or even a regular expression!\n\nRoutes can point to directories. For example the `/` path directs users to the root directory, `/movies` path directs to movies directory.\n\n```javascript\nconst express = require('express')\nconst app = express()\n\n//path with a string\napp.get('/movies', (req, res) =\u003e {\n  res.send('Hello from the root directory!')\n})\n\n//path with a string pattern\napp.get('/movies/:id', (req, res) =\u003e {\n  res.send('Hello from the movies directory!')\n})\n\napp.listen(3000, () =\u003e console.log('The server is listening on port 3000'))\n```\n\nIf we want to access a movie with the id `35`? We can add a specific GET route with the path `/movies/35`.\n\n```javascript\napp.get('/movies/35', (req, res) =\u003e {\n  res.send('Hello. I am the movie with the id 35 in the movies directory!')\n})\n```\n\nBut what if we have a lot of movies? That's where Express dynamic path parameters come in.\n\nWe `add /:` and the parameter name to the path. Like here with `id`.\n\n```javascript\napp.get('/movies/:id', (req, res) =\u003e {\n  res.send('Hello there. I am a route with a parameter called id!')\n})\n```\n\nif we want the value of the movie's `id`, we code `req.params.id`\n\n```javascript\napp.get('/movies/:id', (req, res) =\u003e {\n  res.send(`Hello. I am the movie with the id ${req.params.id} in the movies directory!`\n  )\n})\n```\n\nWe can add more than one parameter to a route's path, like a `name` parameter for the `movies` directory.\n\nHere a request with path `/movies/35/Aliens` gives the value `35` to the `id` parameter and `Aliens` to the `name` parameter.\n\n```javascript\napp.get('/movies/:id/:name', (req, res) =\u003e {\n  res.send(`Hello. I am the movie with the id ${req.params.id} and the name ${req.params.name} in the movies directory!`)\n})\n```\n\nWe can also use destructuring to access parameter values from the `req.params` object and save them in variables.\n\nLet's destructure the parameters with the syntax `const { id, name } = req.params`\n\n```javascript\napp.get('/movies/:id/:name', (req, res) =\u003e {\n  const {id, name} = req.params\n  res.send(`Hello. I am the movie with the id ${id} and the name ${name} in the movies directory!`)\n})\n```\n\n### Middleware in Express\n\n**Middleware** refers to functions that act as an intermediary layer between the web server and the application.\n\nThis intermediary layer allows for more efficient interaction between the server and the app.\n\nMiddleware functions can access the request and response in an application's request-response cycle.\n\nYou can use middleware for tasks like logging information, parsing requests, authentication, and more.\n\nIn Express we add middleware with the `.use()` method.\n\n```javascript\napp.use((req, res) =\u003e { \n  console.log('Incoming request...') \n  console.log(`Request type: ${req.method}`) \n}) \n```\n\nExpress has built-in middleware functions, such as `express.json()`.\n\n`express.json()` parses incoming requests that contain JSON payloads, converting them to a JS object that the server can readily process.\n\n```javascript\nconst express = require(\"express\") \nconst app = express() \n\napp.use(express.json())\n\napp.get('/', (req, res) =\u003e { \n  console.log('The request body JSON is converted to a JS object.') \n}) \n\napp.listen(3000, () =\u003e { \n  console.log('The server is listening on port 3000') \n})\n```\n\nWe can also create our own custom middleware, that does specific custom actions we've defined such as `authenticate`.\n\n```javascript\nfunction authenticate(req, res) { \n  if (req.body.role === 'Admin') { \n    console.log('Authenticated') \n  } else { \n    console.log('Unauthorized') \n  } \n} \n \napp.use(authenticate) \n```\n\nThird-party middleware can also be used. Morgan is a popular middleware used to log HTTP request details.\n\n```javascript\nconst express = require('express') \nconst morgan = require('morgan') \nconst app = express() \n \n// 'tiny' provides logging with minimal output \napp.use(morgan('tiny')) \n \napp.get('/', (req, res) =\u003e { \n  res.status(500).send('Request received.') \n}) \n\napp.listen(3000, () =\u003e { \n    console.log('The server is listening on port 3000') \n})\n```\n\n**Output :**\n\n```bash\nThe server is listening on port 3000\nGET / 200 150 - 1.650 ms\n```\n\nAn important thing to remember is that if we apply `.use()` in our code, none of the code after the middleware function will run. In this code GET request is not handled.\n\n```javascript\napp.use\n((req, res) =\u003e { \n  console.log('Incoming request...') \n  console.log('Request type: ' + req.method) \n  console.log('The flow will stop here.') \n}) \n \napp.get('/', (req, res) =\u003e { \n   console.log(\"Did we make it to the `get()` middleware step?\") \n})\n```\n\nTo move on to the next middleware, we use `next()`. We first need to add `next` to the parameters of the middleware.\n\nThen, we call `next()` at the end of the middleware function.\n\n```javascript\napp.use((req, res, next) =\u003e { \n  console.log('Incoming request...') \n  console.log(`Requesting server: ${req.hostname}`) \n  next() \n}) \n```\n\n### Express Router\n\n**Express Router Basics**\n\nWe know that middleware can be bound to all requests that an Express app receives.\n\nBut how can we assign specific middleware to particular routes? That’s where Express Router comes in!\n\nExpress Router is a module that allows us to bind middleware at the *route* level.\n\nExpress Router does this by using a router object that links an HTTP method and path to specific middleware.\n\nWe'll start with an instance of an Express app in `index.js`. We've also created JS files for each route.\n\nCreating route files is not mandatory but it helps modularize our code. In each route file, we must `require()` Express.\n\nWe need to create an instance of the router object in each of the route files.\n\nIn users.js, declare a variable and assign it an instance of the router object by coding `express.Router()`.\n\n**users.js :**\n\n```javascript\nconst express = require('express')\nconst router =  express.Router()\n```\n\nNow, let's use the router object to create a GET endpoint in `./users.js`.  Use the syntax `router.get()`.\n\nNote that because we'll mount this module to the path `/users` in `index.js`, the path here can simply be `/`.\n\n**users.js :**\n\n```javascript\nconst express = require('express')\nconst router =  express.Router()\n\nrouter.get('/', (req, res) =\u003e {\n  res.send('Get a list of all users')\n})\n```\n\nTo make the route available for use in the application, you'll need to export the modules.\n\nTo do this code `module.exports = router` at the end of the `users.js` file.\n\n```javascript\nconst express = require('express')\nconst router =  express.Router()\n\nrouter.get('/', (req, res) =\u003e {\n  res.send('Get a list of all users')\n})\n\nmodule.exports = router\n```\n\nimport them to the main file `index.js` and bind the modules to their respective routes in our Express application with app.use().\n\n**index.js :**\n\n```javascript\nconst express = require('express')\nconst usersRouter = require('./users.js')\nconst app = express()\n\napp.use('/users', usersRouter)\n\napp.listen(4000, () =\u003e {\n  console.log('The server is listening on port 4000')\n})\n```\n\n**The Router Object**\n\nThe `router.use()` mounts middleware functions to a specific path. When an incoming request's path matches the specified path, the middleware executes.\n\nWe can then mount router on the /products path in app.use(). This allows us to modularize routes.\n\nAny incoming requests to /products/clothing will be handled by the middleware function defined in the router.use() method.\n\n```javascript\nconst express = require('express')\nconst app = express()\nconst router = express.Router()\n\nrouter.use('/clothing', (req, res, nex) =\u003e {\n  console.log('Router use for /clothing)\n})\n\napp.use('/products', router)\n\napp.listen(4000, () =\u003e {\n  console.log('The server is listening on port 4000')\n})\n```\n\nThe `next()` function at the route level serves the same purpose as `next()` at the app level. `next()` calls the next middleware function that matches the request path. We must include next in the callback function's parameters.\n\n```javascript\nconst express = require('express')\nconst app = express()\nconst router = express.Router()\n\nrouter.use('/clothing', (req, res, nex) =\u003e {\n  console.log('Router use for /clothing)\n})\n\nrouter.get('/clothing', (req, res) =\u003e {\n  res.send('Router is getting all clothing info')\n})\n\napp.use('/products', router)\n\napp.listen(4000, () =\u003e {\n  console.log('The server is listening on port 4000')\n})\n```\n\nThe `router.param()` method binds middleware to a specified parameter. Its final argument is the value of the parameter. Here, when a user accesses a path with the parameter `clothingId` we'll see a console log with the parameter's value.\n\n```javascript\nconst express = require('express')\nconst app = express()\nconst router = express.Router()\n\nrouter.param('clothingID', (req, res, next, clothingId) =\u003e {\n  if(clothingId) {\n    console.log(`This is a request for the Clothing ID: ${clothingId}`)\n  }\n  next()\n})\n\nrouter.get('/clothing/:clothingId', (req, res) =\u003e {\n  res.send('Router is getting the request info')\n})\n\napp.use('/products', router)\n\napp.listen(4000, () =\u003e {\n  console.log('The server is listening on port 4000')\n})\n```\n\n`router.route()` allows us to handle all HTTP methods for a single route with one function. Here `router.route()` binds `validateAuth` middleware to handle all HTTP methods for `/users/:userId`, and has distinct callbacks for each method.\n\n```javascript\nconst express = require('express')\nconst app = express()\nconst router = express.Router()\n\nconst validateAuth = (req, res, next) =\u003e {\n  if(req.params.userId) {\n    console.log('User Identified')\n  }\n  next()\n}\n\nrouter.route('/user/:userId')\n.all(validateAuth)\n.get((req, res) =\u003e res.send.('Getting the user information'))\n.post((req, res) =\u003e res.send('Posting the user information'))\n.put((req, res) =\u003e res.send('Updating the user information'))\n.delete((req, res) =\u003e res.send('Deleting the user information'))\n\napp.use('/main', router)\n\napp.listen(4000, () =\u003e {\n  console.log('The server is listening on port 4000')\n})\n```\n\n### Express Error Handling\n\nError handling allows us to provide useful feedback to the frontend and helps avoid server crashes. If the frontend sends a request with errors, the server may not be able to fulfill the request. Send the `GET` request the response when we request a user that does not exist will be 404.\n\n```javascript\nconst express = require('express')\nconst app = express()\n\nconst products = [\n  {category: 'electronics', price: 400, title:'phone', id: 1},\n  {category: 'electronics', price: 900, title:'phone', id: 2},\n  {category: 'electronics', price: 200, title:'phone', id: 3},\n]\n```\n### Structuring GET Endpoints\n\nGET endpoints in Express allow us to send data requested from our server, making it available to manipulate and display on the frontend. In addition to sending data, endpoints enable us to transmit essential information such as HTTP status codes.\n\nFor our examples we'll start by using an array of mock data, so we can focus on structuring our endpoints. For `GET` requests, we'll primarily be retrieving data from the array and sending it back to the client.\n\n`.get()` has two arguments. The first argument is the path that the incoming request is matched to. The path must start with a `/`. The second argument is a callback function with arguments for the request and response objects: `req` and `res`.\n\nIn the callback function, we use the response object res to set the status code, and then we `.send()` the requested information.\n\nRemember to **access the request parameters** if applicable, **query the requested information**, and **send a response** with a status code and body.\n\n```javascript\nconst express = require('express')\nconst app = express()\n\nconst products = [\n  {category: 'electronics', price: 400, title:'phone', id: 1},\n  {category: 'electronics', price: 900, title:'phone', id: 2},\n  {category: 'electronics', price: 200, title:'phone', id: 3},\n]\n\napp.get('/products/:id', (req, res) =\u003e {\n  const params = req.params\n  const requestedProduct = products.find(product =\u003e product.id === Number(params.id))\n  if(!requestedProduct){\n    res.status(404).send({ message: `The product with the id ${ params.id } does not exist`})\n  } else {\n    res.status(200).send(requestedProduct)\n  }\n})\n\napp.listen(3000, () =\u003e {\n  console.log('The server is listening on port 3000')\n})\n```\n\nget from sql example\n\n```javascript\napp.get('/products/:id', (req, res) =\u003e {\n  const productID = req.params.id\n  connection.query('SELECT * FROM Product WHERE id = ?', productID, (error, results) =\u003e {\n    if(error) {\n      res.status.(500).json(error)\n    }\n    res.status(200).send(results)\n  })\n```\n\n### Structuring POST Endpoints\n\n`POST` endpoints in Express allow our server to receive data from the frontend and store it in a database for future retrieval and use.\n\nLike `GET, POST` endpoints start with the instance of the Express application, followed by `.post()`. Like `.get()`, `.post()` has two arguments: the endpoint path and a callback function. The callback has arguments for the `req` and `res` objects.\n\nIn the callback function, we first need to process the data in the req object. The req object holds data about the request. The information we'll need is in the `req` object's body. \n\nAfter accessing the data, we need to add it to the database. Since we're using an array for our database we'll use `.push()` to add the new data.\n\nNext, we need to send a response to the frontend. We'll use a `201` HTTP status code to signify that the data was saved. However, doing this alone is not a complete solution, and can lead to problems if the data wasn't saved properly.\n\nAfter we create new data in a database, it's generally best practice to query the data and return it to the client for verification. Here, we'll use the `.find()` method to locate the entry matching our `newProduct` and save the result in a variable.\n\nFinally, let's use a conditional to verify the entry was added and then send an appropriate response: the confirmed data or an error.\n\nRemember to **get the data** from the request body, **add it** to the database, **confirm** that it was added, and **send** a response to the frontend.\n\n```javascript\nconst express = require('express')\nconst app = express()\n\nconst products = [\n  {category: 'electronics', price: 400, title:'phone', id: 1},\n  {category: 'electronics', price: 900, title:'phone', id: 2},\n  {category: 'electronics', price: 200, title:'phone', id: 3},\n]\n\napp.post('/products', (req, res) =\u003e {\n  console.log('Calling /products endpoint')\n  const newProduct = req.body\n  products.push(newProduct)\n  const confirmEntry = products.find(product =\u003e product === newProduct)\n  if (confirmedEntry) {\n    res.status(201).send(confirmedEntry)\n  } else {\n    res.status(400).send('Error Creating Product')\n  }\n})\n\napp.listen(3000, () =\u003e {\n  console.log('The server is listening on port 3000')\n})\n```\n\npost to sql example\n\n```javascript\napp.post('/products', (req, res) =\u003e {\n  console.log('Calling /products endpoint')\n  const formData = req.body\n  connect.query('INSERT INTO Product set ?', formData, (error, results) =\u003e {\n    if (error) {\n      res.status(500).json(error)\n    }\n    const newProductId = results.insertId\n    connection.query('SELECT * FROM Product WHERE id = ?', newProductId, (error, results) =\u003e {\n      id (error) {\n        res.status(500).json(error)\n      }\n      const newProduct = results[0]\n      res.status(201).send(newProduct)\n    })\n  })\n})\n```\n\n### Structuring DELETE Endpoints\n\nFor a `DELETE` endpoint, our callback function should remove an entry from the database. Below, we update products to only include entries **not** matching the id passed via request parameters.\n\nThen, our DELETE endpoint sends back a copy of the now updated database along with a status code. We also made our endpoint responses robust: if removing an entry fails, the endpoint sends an appropriate status code and response body.\n\n```javascript\nconst express = require('express')\nconst app = express()\n\nconst products = [\n  {category: 'electronics', price: 400, title:'phone', id: 1},\n  {category: 'electronics', price: 900, title:'phone', id: 2},\n  {category: 'electronics', price: 200, title:'phone', id: 3},\n]\n\napp.delete('/products:id', (req, res) =\u003e {\n  const id = request.params.id\n  try {\n    products = products.filter(product =\u003e product.id !== Number(id))\n    response.status(200).send(products)\n  } catch (e) {\n    response.status(404).send({ message: `the product with the id ${params.id} does not exist`})\n  }\n})\n\napp.listen(3000, () =\u003e {\n  console.log('The server is listening on port 3000')\n})\n```\n\ndelete from sql example\n\n```javascript\nrouter.delete('/products/:id', (request, response) =\u003e {\n\tconst productId = request.params.id\n\tconnection.query('DELETE FROM Product WHERE id = ?', productId, (error, results) =\u003e {\n\t\tif (error)\n\t\t\tresponse.status(500).json(error)\n\t\tconnection.query('SELECT * FROM Product', productId, (error, results) =\u003e {\n\t\t\tif (error)\n\t\t\t\tres.status(500).json(error)\n\t\t\tconst updatedDB = results\n\t\t\tresponse.status(200).json(updatedDB)\n\t\t})\n\t})\n})\n```\n\n### Structuring PUT Endpoints\n\n`PUT` endpoints either update an existing entry or insert a new entry if one doesn't exist, so they need to be able to handle both cases.\n\nFirst, inside the callback function, we need to search for a product with a matching `id`. If we find a product with a matching `id`, our PUT endpoint should update the existing entry. Since our database is an array, we can update the existing entry via its index using bracket syntax.\n\nIf we don't find a product with that id, our PUT endpoint should insert a new entry. We'll call `.push()` to add the request body data to the database.\n\nAfter either updating or inserting an entry, our endpoint should access and save the new data to a variable.\n\nFinally, our endpoint should send a response containing the new entry (the one we saved to a variable) along with a status code.\n\n```javascript\nconst express = require('express')\nconst app = express()\n\nconst products = [\n  {category: 'electronics', price: 400, title:'phone', id: 1},\n  {category: 'electronics', price: 900, title:'phone', id: 2},\n  {category: 'electronics', price: 200, title:'phone', id: 3},\n]\n\napp.put('/products:id', (req, res) =\u003e {\n  const params = request.params\n  const body = request.body\n  let index = products.findIndex((product) =\u003e product.id === Number(params.id))\n\n  if (index \u003e= 0) {\n    products[index] = body\n    let confirmedEntry = products[index]\n    response.status(200).send(confirmedEntry)\n  } else {\n    try {\n      products.push(body)\n      let confirmedEntry = products[products.length - 1]\n      response.status(200).send(confirmedEntry)\n    } catch(e) {\n      response.status(404).send({ message: `update failed`})\n    }\n  }\n})\n\napp.listen(3000, () =\u003e {\n  console.log('The server is listening on port 3000')\n})\n```\n\nput to sql example\n\n```javascript\napp.put('/products/:id', (request,\n\tresponse) =\u003e {\n\tconst productId = request.params.id\n\tconst formData = request.body\n\tconnection.query('UPDATE Product SET ? WHERE id = ?',[formData, productId], (error, results) =\u003e {\n\t\tif (error)\n\t\t\tres.status(500).json(error)\n\t\tconnection.query('SELECT * FROM Product WHERE id = ?',productId, (error, results) =\u003e {\n\t\t  if (error)\n\t\t\t  res.status(500).json(error)\n\t\t  const updatedProduct = results\n\t\t\tresponse.status(200).json(updatedProduct)\n\t\t\t})\n\t})\n})\n```\n\n### Connecting to a Database\n\n**How to connect to Database**\n\nTo connect to a database, we need to import the `mysql` module. The mysql module has functions to help with connecting to a database. One such function is `createConnection()`. We use `createConnection()` to define the connection details like the server, the credentials, and the database name.\n\n```javascript\nconst mysql = require('mysql)\nconst connection = mysql.createConnection()\n```\n\nTo connect to a database, the program needs to know where the database is. The host property of the object defines this information. \n\nConnecting to a database usually requires credentials. Aside from the host, we should also include the user and password properties.\n\nMultiple databases can share the same host. We can include the database property in the object to define which database to connect to.\n\n```javascript\nconst mysql = require('mysql)\nconst connection = mysql.createConnection({\n  host: 'localhost',\n  user: 'myUser',\n  password: 'myPassword',\n  database: 'myDB\n})\n```\n\n**Test connection with Database**\n\n`createConnection()` only holds the details for the database connection. To connect to the database, we need to use the `connect()` function.\n`connection.connect()`\n\nThe `connect()` function initiates a connection to the server but will **not** show if the connection was successful. To check the connection, we can add an arrow function as the parameter of `connect()`. The function should take an argument, `error`.\n`connection.connect(error =\u003e {})`\n\nThe function alone is not enough to let us know if there is an error. We need to use an if statement to check if `error` has a value. If `error` has a value, we should `throw` the `error`. Otherwise, we can print a message in the console that says `'Connected!'`.\n```javascript\nconnection.ceonnect(error =\u003e {\n  if(error) {\n    throw error\n  }\n  console.log(\"Connected!\")\n}\n```\n\nIt's good practice to always end your connection. This ensures that all queries are executed before the database connection is closed. The `mysql` module has an `end()` function that we can use to end the connection.\n`connection.end()`\n\nWhen we try to close a database connection, we might encounter errors. Therefore, like with `connect()`, we'll also need to pass a callback function that checks for errors as an argument for `end()`.\n\n```javascript\nconnection.end(error =\u003e {\n  if(error) {\n    throw error\n  }\n  console.log(\"Connection closed!\")\n})\n```\n\n**Environment Variables**\n\nWhen establishing a connection, the details like host or password are the same throughout all the web pages. *Environment* variables help us save time when coding because we only need to include these details in one file.\n\nEnvironment variables are like any other variables, the only difference is that they are usable on a global scope, across multiple files. To use environment variables, we need the dotenv module and its `config()` function.\n`require.('dotenv').config()`\n\nAside from `dotenv`, we also need the `process` module but `process` is a built-in module and does not need to be imported. We can use the `env` property of the `process` module to access the environment variables.\n\n```javascript\nrequire('dotenv').config()\n\nconst mysql = require('mysql)\nconst connection = mysql.createConnection({\n  host: process.env.HOST,\n  user: 'myUser',\n  password: 'myPassword',\n  database: 'myDB'\n})\n```\n\nBut where are the environment variables? We can store all the environment variables in a separate `.env` file. We create them like this: `VARIABLE_NAME = 'value'`. Give the value `localhost` to the `HOST` environment variable.\n`HOST='localhost'`\n\nTo access the environment variables stored in the `.env` file we code `process.env` followed by `.` and the variable name.\n\n```env\nHOST='localhost'\nDATABASE='myDB'\nPASSWORD='myPassword'\nUSER='myUser'\n```\nrequire('dotenv').config()\n\nconst mysql = require('mysql)\nconst connection = mysql.createConnection({\n  host: process.env.HOST,\n  user: process.env.USER,\n  password: process.env.PASSWORD,\n  database: process.env.DATABASE\n})\n```javascript\n```\n\n### Database Interactions\n\n**Querying Database**\n\nWe know `APIs` help us connect front-end and back-end, but how are `APIs` created? Let's create an `API` using `query()` and router!\n\nTo execute SQL statements on a MySQL database using Node.js, we can use the `query()` function from the `mysql` module. The `query()` function takes 2 parameters: the SQL statement to be executed and a callback function to process the response.\n\nThe callback function used as the 2nd parameter of `query()` only accepts 2 parameters. This is because we only need the first 2 parts which are `error` and `result` but the response could actually have more than 2 parts.\n\n```javascript\nconst mysql = require('mysql')\nconst con = mysql.createConnection({\n  host: \"host\",\n  user: \"user\",\n  password: \"pw\",\n  database: \"db\"\n})\ncon.connect(err =\u003e {\n  if(err) throw err\n  con.query(\"SELECT * FROM customers\", (error, result) =\u003e {\n    if(error) throw error\n    console.log(result)\n  })\n})\n```\n\nFor `SELECT` statements used as the first parameter of the `query()` function, the result is returned as an array of objects. Logging result will print all columns queried. The syntax to access specific value is `result[index].column_name`.\n`console.log(result[index].column_name)`\n\n**Inserting into Database**\n\nWe can use `query()` like we do when we retrieve data. However, instead of a `SELECT` statement for the first parameter, we use an `INSERT INTO` statement.\n\n```javascript\nconst mysql = require('mysql')\nconst con = mysql.createConnection({\n  host: \"host\",\n  user: \"user\",\n  password: \"pw\",\n  database: \"db\"\n})\ncon.connect(err =\u003e {\n  if(err) throw err\n  con.query(\"INSERT INTO customers (name) VALUES ('Company ABC')\", (error, result) =\u003e {\n    if(error) throw error\n    console.log(result)\n  })\n})\n```\n\nTo parameterize a SQL statement, simply add `?` where we would enter values. For our example, that is after `VALUES`.\n`con.query(\"INSERT INTO customers (name) VALUES ?\", () =\u003e {})`\n\nNext, we need to store the values in a 2-dimensional array. We'll use this array as the 2nd parameter of `query()`. Each row is an array and we store columns as the elements of each row. These row arrays are then all stored in one array.\n\n```javascript\ncon.query(\"INSERT INTO customers (name) VALUES ?\", \n  [\n    ['ABC Company]', '2001'],\n    ['DEF Corp', '1998'],\n    ['GHI Inc.', '2015']\n  ]\n,() =\u003e {})\n```\n\nUnlike `SELECT` statements, `INSERT INTO` statements do not respond with data from the database. We can use the `affectedRows` property of `result` to see the number of new rows added.\n\n```javascript\ncon.query(\"INSERT INTO customers (name) VALUES ?\", \n  [\n    ['ABC Company]', '2001'],\n    ['DEF Corp', '1998'],\n    ['GHI Inc.', '2015']\n  ]\n,(error, result) =\u003e {\n  if(error) throw error\n  console.log(result.affectedRows)\n})\n```\n\n**Integrating with Router**\n\nWe learned that an `API` can have different actions based on the HTTP method. Such `APIs` can be created using `router` and `query()`. Now, we'll learn how we can create these `APIs` and how we can allow an `API` to perform different actions.\n\n```javascript\nconst mysql = require('mysql')\nconst DB_HOST = 'localhost'\nconst DB_USER = 'root'\nconst DB_PASSWORD = 'example_password'\nconst DATABASE = 'example_db'\nconst router = express.Router()\nconst connection =\n\tmysql.createConnection({\n\t\thost: DB_HOST,\n\t\tuser: DB_USER,\n\t\tpassword: DB_PASSWORD,\n\t\tdatabase: DATABASE\n\t})\nrouter.get('/products', (req, res) =\u003e {\n\tconnection.query('SELECT * FROM products', (error, results) =\u003e {\n\t\tif (error) {\n\t\t\tconsole.log(error)\n\t\t\tres.status(500).send('There is an issue with your request.')\n\t\t} else {\n\t\t\tconst products = results\n\t\t\tres.status(200).json(products)\n\t\t}\n\t})\n})\n```\n\nWe can use the `post()` function to handle the request with the HTTP POST method. We can also use `query()` in the callback function of `router.post()` to execute an `INSERT INTO` statement on the database to insert data.\n\n```javascript\nconst mysql = require('mysql')\nconst DB_HOST = 'localhost'\nconst DB_USER = 'root'\nconst DB_PASSWORD = 'example_password'\nconst DATABASE = 'example_db'\nconst router = express.Router()\nconst connection =\n\tmysql.createConnection({\n\t\thost: DB_HOST,\n\t\tuser: DB_USER,\n\t\tpassword: DB_PASSWORD,\n\t\tdatabase: DATABASE\n\t})\nrouter.post('/products', (req, res) =\u003e {\n\tconnection.query('INSERT INTO products VALUES (3,\"Potted Plant\" ,9.90)', (error, results) =\u003e {\n\t\tif (error) {\n\t\t\tconsole.log(error)\n\t\t\tres.status(500).send('There is an issue with your request.')\n\t\t} else {\n\t\t\tres.status(200).json(\"{'Rows':\" + results.affectedRows + \"}\")\n\t\t}\n\t})\n})\n```\n\nWe can parameterize the SQL statement, then use the `body` property of the request as the second parameter to insert multiple values.\n`connection.query('INSERT INTO products VALUES ?', req.body, () =\u003e {})`\n\nWe can use the `put()` function to handle the request with the HTTP PUT method. For requests involving identification, we can append `/:id` to the endpoint to be used as reference later.\n\n```javascript\nconst mysql = require('mysql')\nconst DB_HOST = 'localhost'\nconst DB_USER = 'root'\nconst DB_PASSWORD = 'example_password'\nconst DATABASE = 'example_db'\nconst router = express.Router()\nconst connection =\n\tmysql.createConnection({\n\t\thost: DB_HOST,\n\t\tuser: DB_USER,\n\t\tpassword: DB_PASSWORD,\n\t\tdatabase: DATABASE\n\t})\nrouter.post('/products/:id', (req, res) =\u003e {\n\tconnection.query('UPDATE products SET name = ? WHERE id=' + req.params.id, req.body, (error, results) =\u003e {\n\t\tif (error) {\n\t\t\tconsole.log(error)\n\t\t\tres.status(500).send('There is an issue with your request.')\n\t\t} else {\n\t\t\tres.status(200).json(\"{'Rows':\" + results.affectedRows + \"}\")\n\t\t}\n\t})\n})\n```\n\n\n## MongoDB Cheat Sheet\n\n### The MongoDB Document Model\n\n[https://www.mongodb.com/developer/products/mongodb/cheat-sheet/#table-of-contents]\n\n**Document Structure**\n\nThe values in a document can be any data type, including strings, objects, arrays, booleans, nulls, dates, ObjectIds, and more. Here's the syntax for a MongoDB document, followed by an example:\n\nSyntax:\n\n```javascript\n{\n    \"key\": value,\n    \"key\": value,\n    \"key\" : value\n}\n```\n\nExample:\n\n```javascript\n{\n    \"_id\": 1,\n    \"name\": \"AC3 Phone\",\n    \"colors\" : [\"black\", \"silver\"],\n    \"price\" : 200,\n    \"available\" : true\n}\n```\n\n### Referencing Data in Documents\n\n**Embeding**\n\nPros: \n- Single query to retrieve data\n- Single operation to update/delete\n\nCons:\n- Data duplication\n- Large documents\n\n**Referencing**\n\nPros:\n- No duplication\n- Smaller documents\n\nCons:\n- Need to join data from multiple documents\n\n### CRUD Operation: Insert and Find Documents\n\n**Insert a Single Document**\n\nUse `insertOne()` to insert a document into a collection. Within the parentheses of `insertOne()`, include an object that contains the document data. Here's an example:\n\n```javascript\ndb.grades.insertOne({\n  student_id: 654321,\n  products: [\n    {\n      type: \"exam\",\n      score: 90,\n    },\n    {\n      type: \"homework\",\n      score: 59,\n    },\n    {\n      type: \"quiz\",\n      score: 75,\n    },\n    {\n      type: \"homework\",\n      score: 88,\n    },\n  ],\n  class_id: 550,\n})\n```\n\n**Insert Multiple Documents**\n\nUse `insertMany()` to insert multiple documents at once. Within `insertMany()`, include the documents within an array. Each document should be separated by a comma. Here's an example:\n\n```javascript\ndb.grades.insertMany([\n  {\n    student_id: 546789,\n    products: [\n      {\n        type: \"quiz\",\n        score: 50,\n      },\n      {\n        type: \"homework\",\n        score: 70,\n      },\n      {\n        type: \"quiz\",\n        score: 66,\n      },\n      {\n        type: \"exam\",\n        score: 70,\n      },\n    ],\n    class_id: 551,\n  },\n  {\n    student_id: 777777,\n    products: [\n      {\n        type: \"exam\",\n        score: 83,\n      },\n      {\n        type: \"quiz\",\n        score: 59,\n      },\n      {\n        type: \"quiz\",\n        score: 72,\n      },\n      {\n        type: \"quiz\",\n        score: 67,\n      },\n    ],\n    class_id: 550,\n  },\n  {\n    student_id: 223344,\n    products: [\n      {\n        type: \"exam\",\n        score: 45,\n      },\n      {\n        type: \"homework\",\n        score: 39,\n      },\n      {\n        type: \"quiz\",\n        score: 40,\n      },\n      {\n        type: \"homework\",\n        score: 88,\n      },\n    ],\n    class_id: 551,\n  },\n])\n```\n\n**Find a Document with Equality**\n\nWhen given equality with an `_id` field, the `find()` command will return the specified document that matches the `_id`. Here's an example:\n\n```javascript\ndb.zips.find({ _id: ObjectId(\"5c8eccc1caa187d17ca6ed16\") })\n```\n\n**Find a Document by Using the `$in` Operator**\n\nUse the `$in` operator to select documents where the value of a field equals any value in the specified array. Here's an example:\n\n```javascript\ndb.zips.find({ city: { $in: [\"PHOENIX\", \"CHICAGO\"] } })\n```\n\n**Finding Documents by Using Comparison Operators**\n\n- `$gt`\n    operator to match documents with a field **greater than** the given value. For example: \n    ```javascript\n    db.sales.find({ \"items.price\": { $gt: 50}})\n    ```\n\n- `$lt`\n    operator to match documents with a field **less than** the given value. For example: \n    ```javascript\n    db.sales.find({ \"items.price\": { $lt: 50}})\n    ```\n\n- `$lte`\n    operator to match documents with a field **less than or equal to** the given value. For example: \n    ```javascript\n    db.sales.find({ \"customer.age\": { $lte: 65}})\n    ```\n\n- `$gte`\n    operator to match documents with a field **greater than or equal to** the given value. For example: \n    ```javascript\n    db.sales.find({ \"customer.age\": { $gte: 65}})\n    ```\n\n**Find Documents with an Array That Contains a Specified Value**\n\nin the following example, \"InvestmentFund\" is not enclosed in square brackets, so MongoDB returns all documents within the `products` array that contain the specified value.\n\n```javascript\ndb.accounts.find({ products: \"InvestmentFund\"})\n```\n\n**Find a Document by Using the `$elemMatch` Operator**\n\nUse the `$elemMatch` operator to find all documents that contain the specified subdocument. For example:\n\n```javascript\ndb.sales.find({\n  items: {\n    $elemMatch: { name: \"laptop\", price: { $gt: 800 }, quantity: { $gte: 1 } },\n  },\n})\n```\n\n**Find a Document by Using Implicit `$and`**\nUse implicit `$and` to select documents that match multiple expressions. For example:\n\n```javascript\ndb.routes.find({ \"airline.name\": \"Southwest Airlines\", stops: { $gte: 1 } })\n```\n\n**Find a Document by Using the `$or` Operator**\n\nUse the `$or` operator to select documents that match at least one of the included expressions. For example:\n\n```javascript\ndb.routes.find({\n  $or: [{ dst_airport: \"SEA\" }, { src_airport: \"SEA\" }],\n})\n```\n\n**Find a Document by Using the `$and` Operator**\n\nUse the `$and` operator to use multiple `$or` expressions in your query.\n\n```javascript\ndb.routes.find({\n  $and: [\n    { $or: [{ dst_airport: \"SEA\" }, { src_airport: \"SEA\" }] },\n    { $or: [{ \"airline.name\": \"American Airlines\" }, { airplane: 320 }] },\n  ]\n})\n```\n\n### CRUD Operations: Replace and Delete Documents\n\n**Replacing a Document in MongoDB**\n\nTo replace documents in MongoDB, we use the `replaceOne()` method. The `replaceOne()` method takes the following parameters:\n- `filter`: A query that matches the document to replace.\n- `replacement`: The new document to replace the old one with.\n- `options`: An object that specifies options for the update.\n\n```javascript\ndb.books.replaceOne(\n  {\n    _id: ObjectId(\"6282afeb441a74a98dbbec4e\"),\n  },\n  {\n    title: \"Data Science Fundamentals for Python and MongoDB\",\n    isbn: \"1484235967\",\n    publishedDate: new Date(\"2018-5-10\"),\n    thumbnailUrl:\n      \"https://m.media-amazon.com/images/I/71opmUBc2wL._AC_UY218_.jpg\",\n    authors: [\"David Paper\"],\n    categories: [\"Data Science\"],\n  }\n)\n```\n\n**Updating MongoDB Documents by Using `updateOne()`**\n\nThe `updateOne()` method accepts a filter document, an update document, and an optional options object. MongoDB provides update operators and options to help you update documents. In this section, we'll cover three of them: `$set`, `upsert`, and `$push`.\n\n- `$set`\n    operator replaces the value of a field with the specified value, as shown in the following code:\n\n    ```javascript\n    db.podcasts.updateOne(\n        {\n            _id: ObjectId(\"5e8f8f8f8f8f8f8f8f8f8f8\"),\n        },\n\n        {\n            $set: {\n                subscribers: 98562,\n            },\n        }\n    )\n  ```\n\n- `upsert`\n    option creates a new document if no documents match the filtered criteria. Here's an example:\n\n    ```javascript\n    db.podcasts.updateOne(\n        { title: \"The Developer Hub\" },\n        { $set: { topics: [\"databases\", \"MongoDB\"] } },\n        { upsert: true }\n    )\n    ```\n\n- `$push`\n    operator adds a new value to the hosts array field. Here's an example:\n\n    ```javascript\n    db.podcasts.updateOne(\n        { _id: ObjectId(\"5e8f8f8f8f8f8f8f8f8f8f8\") },\n        { $push: { hosts: \"Nic Raboy\" } }\n    )\n    ```\n\n**Updating MongoDB Documents by Using `findAndModify()`**\n\nThe `findAndModify()` method is used to find and replace a single document in MongoDB. It accepts a filter document, a replacement document, and an optional options object. The following code shows an example:\n\n```javascript\ndb.podcasts.findAndModify({\n  query: { _id: ObjectId(\"6261a92dfee1ff300dc80bf1\") },\n  update: { $inc: { subscribers: 1 } },\n  new: true,\n})\n```\n\n**Updating MongoDB Documents by Using `updateMany()`**\n\nTo update multiple documents, use the `updateMany()` method. This method accepts a filter document, an update document, and an optional options object. The following code shows an example:\n\n```javascript\ndb.books.updateMany(\n  { publishedDate: { $lt: new Date(\"2019-01-01\") } },\n  { $set: { status: \"LEGACY\" } }\n)\n```\n\n**Deleting Documents in MongoDB**\n\nTo delete documents, use the `deleteOne()` or `deleteMany()` methods. Both methods accept a filter document and an options object.\n\n- `deleteOne()`\n\n    ```javascript\n    db.podcasts.deleteOne({ _id: Objectid(\"6282c9862acb966e76bbf20a\") })\n    ```\n- `deleteMany()`\n\n    ```javascript\n    db.podcasts.deleteMany({category: “crime”})\n    ```\n\n### CRUD Operations: Modify Query Results\n\n**Sorting Query Results**\n\nUse `cursor.sort()` to return query results in a specified order. Within the parentheses of `sort()`, include an object that specifies the field(s) to sort by and the order of the sort. Use 1 for ascending order, and -1 for descending order.\n\nSyntax:\n\n```javascript\ndb.collection.find(\u003cquery\u003e).sort(\u003csort\u003e)\n```\n\nExample:\n\n```javascript\n// Return data on all music companies, sorted alphabetically from A to Z.\ndb.companies.find({ category_code: \"music\" }).sort({ name: 1 });\n```\n\nTo ensure documents are returned in a consistent order, include a field that contains unique values in the sort. An easy way to do this is to include the `_id` field in the sort. Here's an example:\n\n```javascript\n// Return data on all music companies, sorted alphabetically from A to Z. Ensure consistent sort order\ndb.companies.find({ category_code: \"music\" }).sort({ name: 1, _id: 1 });\n```\n\n****Limiting Query Results**\n\nUse `cursor.limit()` to specify the maximum number of documents the cursor will return. Within the parentheses of `limit()`, specify the maximum number of documents to return.\n\nSyntax:\n\n```javascript\ndb.companies.find(\u003cquery\u003e).limit(\u003cnumber\u003e)\n```\n\nExample:\n\n```javascript\n// Return the three music companies with the highest number of employees. Ensure consistent sort order.\ndb.companies\n  .find({ category_code: \"music\" })\n  .sort({ number_of_employees: -1, _id: 1 })\n  .limit(3);\n```\n\n**Add a Projection Document**\n\nTo specify fields to include or exclude in the result set, add a projection document as the second parameter in the call to `db.collection.find()`.\n\nSyntax:\n\n```javascript\ndb.collection.find( \u003cquery\u003e, \u003cprojection\u003e )\n```\n\n**Include a Field**\n\nTo include a field, set its value to 1 in the projection document.\n\nSyntax:\n\n```javascript\ndb.collection.find( \u003cquery\u003e, { \u003cfield\u003e : 1 })\n```\n\nExample:\n\n```javascript\n// Return all restaurant inspections - business name, result, and _id fields only\ndb.inspections.find(\n  { sector: \"Restaurant - 818\" },\n  { business_name: 1, result: 1 }\n)\n```\n\n**Exclude a Field**\n\nTo exclude a field, set its value to 0 in the projection document.\n\nSyntax:\n\n```javascript\ndb.collection.find(query, { \u003cfield\u003e : 0, \u003cfield\u003e: 0 })\n```\n\nExample:\n\n```javascript\n// Return all inspections with result of \"Pass\" or \"Warning\" - exclude date and zip code\ndb.inspections.find(\n  { result: { $in: [\"Pass\", \"Warning\"] } },\n  { date: 0, \"address.zip\": 0 }\n)\n```\n\nWhile the `_id` field is included by default, it can be suppressed by setting its value to 0 in any projection.\n\n```javascript\n// Return all restaurant inspections - business name and result fields only\ndb.inspections.find(\n  { sector: \"Restaurant - 818\" },\n  { business_name: 1, result: 1, _id: 0 }\n)\n```\n\n**Count Documents**\n\nUse `db.collection.countDocuments()` to count the number of documents that match a query. `countDocuments()` takes two parameters: a query document and an options document.\n\nSyntax:\n\n```javacript\ndb.collection.countDocuments( \u003cquery\u003e, \u003coptions\u003e )\n```\n\nExample:\n\n```javascript\n// Count number of docs in trip collection\ndb.trips.countDocuments({})\n// Count number of trips over 120 minutes by subscribers\ndb.trips.countDocuments({ tripduration: { $gt: 120 }, usertype: \"Subscriber\" })\n```\n\n### CRUD Operations in Node.js\n\n**Insert a Document**\n\nTo insert a single document into a collection, append `insertOne()` to the collection variable. The `insertOne()` method accepts a document as an argument and returns a promise. In this example, the document that's being inserted is stored in a variable called `sampleAccount`, which is declared just above the `main()` function.\n\n```javascript\nconst dbname = \"bank\"\nconst collection_name = \"accounts\"\n \nconst accountsCollection = client.db(dbname).collection(collection_name)\n\nconst sampleAccount = {\n account_holder: \"Linus Torvalds\",\n account_id: \"MDB829001337\",\n account_type: \"checking\",\n balance: 50352434,\n}\n\nconst main = async () =\u003e {\n try {\n   await connectToDatabase()\n   // insertOne method is used here to insert the sampleAccount document\n   let result = await accountsCollection.insertOne(sampleAccount)\n   console.log(`Inserted document: ${result.insertedId}`)\n } catch (err) {\n   console.error(`Error inserting document: ${err}`)\n } finally {\n   await client.close()\n }\n}\n \nmain()\n```\n\n**Insert Many Documents**\n\nTo insert more than one document, append the `insertMany()` method to the `collection` object, and then pass an array of documents to the `insertMany()` method. The `insertMany()` method returns a promise. We await the promise to get the result of the operation, which we then use to log the number of documents that are inserted to the console. In this example, the accounts to be inserted are stored in an array variable called `sampleAccounts`. This variable is defined just above the main() function.\n\n```javascript\nconst dbname = \"bank\"\nconst collection_name = \"accounts\"\n \nconst accountsCollection = client.db(dbname).collection(collection_name)\n\nconst sampleAccounts = [\n {\n   account_id: \"MDB011235813\",\n   account_holder: \"Ada Lovelace\",\n   account_type: \"checking\",\n   balance: 60218,\n },\n {\n   account_id: \"MDB829000001\",\n   account_holder: \"Muhammad ibn Musa al-Khwarizmi\",\n   account_type: \"savings\",\n   balance: 267914296,\n },\n]\n \nconst main = async () =\u003e {\n try {\n   await connectToDatabase()\n   let result = await accountsCollection.insertMany(sampleAccounts)\n   console.log(`Inserted ${result.insertedCount} documents`)\n   console.log(result)\n } catch (err) {\n   console.error(`Error inserting documents: ${err}`)\n } finally {\n   await client.close()\n }\n}\n\nmain()\n```\n\n**Using `find()`**\n\nThe `find()` method is a read operation that returns a cursor to the documents that match the query. The `find()` method takes a query or filter document as an argument. If you do not specify a query document, the `find()` method returns all documents in the collection.\n\nIn this example, we find all accounts that have a balance greater than or equal to 4700. The `find()` method accepts a query filter, which we assign to a variable called `documentsToFind`. We process each document that’s returned from the `find()` method by iterating the cursor, which is assigned to the variable `result`.\n\n```javascript\nconst dbname = \"bank\"\nconst collection_name = \"accounts\"\n \nconst accountsCollection = client.db(dbname).collection(collection_name)\n\n// Document used as a filter for the find() method\nconst documentsToFind = { balance: { $gt: 4700 } }\n \nconst main = async () =\u003e {\n try {\n   await connectToDatabase()\n   // find() method is used here to find documents that match the filter\n   let result = accountsCollection.find(documentsToFind)\n   let docCount = accountsCollection.countDocuments(documentsToFind)\n   await result.forEach((doc) =\u003e console.log(doc))\n   console.log(`Found ${await docCount} documents`)\n } catch (err) {\n   console.error(`Error finding documents: ${err}`)\n } finally {\n   await client.close()\n }\n}\n\nmain()\n```\n\n**Using `findOne()`**\n\nIn this example, we return a single document from a query, which is assigned to a variable called `documentToFind`. We use the `findOne()` method on the collection object to return the first document that matches the filter criteria, which are defined in the `documentToFind` variable.\n\n```javascript\nconst dbname = \"bank\"\nconst collection_name = \"accounts\"\n \nconst accountsCollection = client.db(dbname).collection(collection_name)\n\n// Document used as a filter for the findOne() method\nconst documentToFind = { _id: ObjectId(\"62a3638521a9ad028fdf77a3\") }\n\nconst main = async () =\u003e {\n try {\n   await connectToDatabase()\n   // findOne() method is used here to find a the first document that matches the filter\n   let result = await accountsCollection.findOne(documentToFind)\n   console.log(`Found one document`)\n   console.log(result)\n } catch (err) {\n   console.error(`Error finding document: ${err}`)\n } finally {\n   await client.close()\n }\n}\n\nmain()","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphurin-git%2Fdev-playground","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphurin-git%2Fdev-playground","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphurin-git%2Fdev-playground/lists"}