<style>
@import url('https://fonts.googleapis.com/css?family=Roboto+Mono&display=swap');
.reveal {
font-family: "Roboto Mono", monospace;
font-size: 40px;
}
</style>
# Intro to MERN -- Node/Express
##### We will need Node (https://nodejs.org/en/download/) for this workshop, and GitBash (https://gitforwindows.org/) for Windows if you do not have access to a console
###### tags: `MERN`
---
## Web Development

To further understand this, let's take a look at the steps the backend goes through from when it receives a request to when it sends a response back to the client.
----
When a client enters a URL on the browser, a request is sent to the server. The server obtains the information it needs to determine what the user is asking for.

----
The server will then send back a response to the client based on the specified path and query string.
Usually, this is in the form of an HTML page, which will get rendered and displayed to the user.
It can also send back data as JSON, or even just an HTTP status code (i.e 404 - Not Found)
----
The backend also includes the *database*, which is where all of the data is stored.
Requests sent to the server might require a database query. The client might need to request information stored in the database, or they might submit data to be added to the database.
In this workshop, we'll be setting up a server that will be used to query the database from MongoDB (next workshop!).
---
## What's Node?
* Node is a Javascript Runtime Environment
* JavaScript only lets us modify code on the browsers (Chrome, Firefox, etc.)
* Node allows us to use JavaScript on the server (back-end) 😮
* Fast and efficient
* Works on a single thread, but slow when CPU intensive
----
## Another Benefit - NPM 🙌
* Node Package Manager
* Makes it easier to install 3rd party packages
* Ex. Frameworks, libraries, tools, etc)
* Packages stored in node_modules and dependencies in package.json
----
1. Install node.js
- https://nodejs.org/en/download/
- To confirm that node is ready to go:
- ```node --version```
- ```npm --version```
2. `mkdir mern-workshop` to create our project directory
3. `cd mern-workshop`
4. `mkdir backend` to create a directory for our backend code
5. `cd backend`
6. `npm init` -- Generates a package.json file
---
## What's Express?
* Express is a back-end framework that works with Node
* Makes building web applications easier by reducing the amount code
* Fast, light, and allows full control of server requests and responses
* Common commands
* ```app.get(), app.post(), app.delete(), app.put()```
[Express Routing](https://expressjs.com/en/starter/basic-routing.html)
----
### HTTP Request Methods
1. GET - request data from the server
2. POST - send data to the server to create a resource
3. PUT - send data to the server to update a resource
4. DELETE - delete data from the server
And many more...
See [here](https://restfulapi.net/http-methods/) for a more detailed explanation of these methods
---
# Setting Up the Server
----
1. ```npm install express```
* Installs express
3. Create an index.js file
----
## index.js
``` javascript
const express = require('express');
// Initialize express
const app = express();
// Home Page Route
app.get('/', function(req, res) {
res.send('<h1>Hello World!</h1>');
});
// Listen on a port
app.listen(3000);
```
----

----
3. Now exit index.js
4. Go into package.json and add underneath scripts
```javascript
"start": "node index.js",
```
Here, we're setting `npm start` to run the command `node index.js`
5. To start the server, use `npm start` (in terminal)
6. Now open up a new browser tab with the url of **localhost:3000/**
🏁 Checkpoint 1 🏁: You should see Hello World! displayed on the screen! 👋
---
# Adding Routing
----
1. Use `mkdir` to create a folder called *routes*
2. Inside this folder create a file called *users.js*
```javascript
// Imports express
const express = require('express');
// Get express' Router object
const router = express.Router();
// Make a GET request to get a list of Users
router.route('/').get((req, res) => {
res.send('<h1>User Request</h1>');
});
// Make a POST request to add a User
router.route('/add').post((req, res) => {
res.send('<h1>Added User</h1>');
});
// exports the Router object so we can use it in index.js
module.exports = router;
```
----
3. To use the router module we just made in *users.js*, we first `require()` it by adding this on top of the index.js file:
``` javascript
const usersRoute = require('./routes/users');
```
4. We then use `app.use()` to specify the URL path of /users and connect it to the routes we created in *users.js*:
```javascript
app.use('/users', usersRoute);
```
The two routes defined in our users route module are then accessible from `/users/` and `/users/add/`.
----
Now, let's test the routes we just made, starting with `/users/`!
5. Exit index.js and run `npm start`
6. Add /users/ to the url (the browser will send a GET request to our server)
🏁 Checkpoint 2 🏁: You should see "User Request" displayed!
----
In order to test the `/users/add` route, we need to send a POST request to the server.
We'll do that by making a form to send a POST request once submitted.
Create an index.html file:
```htmlmixed=
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title> Index.html </title>
</head>
<body>
<form method="POST" action="/users/add">
<label> Name: </label>
<input type="name" name="name"></input> <br>
<button type="submit"> Submit </button>
</form>
</body>
</html>
```
----
Display the index.html page through our Home Page route.
In index.js, change the `/` route to:
``` javascript
const path = require('path');
// Home Page Route
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname, 'index.html'));
});
```
----
With this form, you can test the '/users/add' route.
🏁 Checkpoint 3 🏁: "Added User" should be displayed on your screen!
----
Now that we have the form set up, we'll actually retrieve the data sent to /users/add and display that in our response.
Go back to *users.js* and make the following changes to the /add route:
```javascript
// Sends data to the server
router.route('/add').post((req, res) => {
// get the name from the form request
const name = req.body.name;
// send an h1 element introducing the user
res.send('<h1>Hi, my name is ' + name + '</h1>')
})
```
----
5. Add this to your index.js too, after the line app = express():
```javascript
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended: true}));
```
Body parser extracts the entire body of the incoming request (a.k.a. the data we are sending, such as the user's name) and puts it into req.body for us to use. Without this, we would get an empty body, even if we pass in data.
----
🏁 Checkpoint 4 🏁: You should see "Hi, my name is `<name>`" displayed when you submit the form!
----
## Your Turn!
### Task: Add routes for tweets.js that supports viewing, adding, and deleting
👉 '`/`' displays "View Tweets"
👉 '`/add`' displays "Tweet Added"
👉 '`/delete/:id`' displays "Tweet `<id>` deleted"
Extra Credit 💸 '`/update/:id`' displays "Tweet `<id>` updated"
---
# Adding Local Storage
* LocalStorage allows you to store data on the browser and persist data through browser refreshes
* Local Storage is similar to using a hash_map(java) / unordered_map(c++) / dictionary(python)
----
* To store data you use the line:
* ```localStorage.setItem('key', 'value');```
* To access data:
* ```let value = localStorage.getItem('key');```
* To remove data:
* ```localStorage.removeItem('key');```
* ```localStorage.clear();```
* Removes the whole storage
----
Example: we want to store an array of users called users
``` javascript
localStorage.setItem('users', JSON.stringify(users));
let listOfUsers = JSON.parse(localStorage.getItem('users'));
```
----
Extra Extra Credit 💸💸: Try setting up a local storage that stores user input from the form and send them back as a response!
---
## That's all! Next workshop: MongoDB 🍃
* Resources used:
* https://www.youtube.com/watch?v=fBNz5xF-Kx4
* https://www.youtube.com/watch?v=L72fhGm1tfE
{"metaMigratedAt":"2023-06-15T03:03:52.577Z","metaMigratedFrom":"Content","title":"Intro to MERN -- Node/Express","breaks":true,"contributors":"[{\"id\":\"0ffe3cdf-ee91-4b9a-9e67-32d09c41aec9\",\"add\":7557,\"del\":4528},{\"id\":\"25be75a2-9a21-4137-a70a-c55f361a5189\",\"add\":1813,\"del\":515},{\"id\":\"705ab2b0-5942-4ee9-82b9-dfe9025b89f7\",\"add\":9610,\"del\":5523},{\"id\":\"5b2ddf1d-ac67-49e8-a0b5-4640a3bc31a8\",\"add\":100,\"del\":24}]"}