Node ExpressJS
Node ExpressJS
NodeJS:
- A JavaScript runtime written in C++.
- Can interpret and execute JavaScript.
- Includes support for the NodeJS API.
NodeJS API:
- A set of JavaScript libraries that are useful for creating
server programs.
V8 (from Chrome):
- The JavaScript interpreter ("engine") that NodeJS uses
to interpret, compile, and execute JavaScript code
NodeJS
NodeJS:
- A JavaScript runtime written in C++.
Q: What does
- Can interpret and execute JavaScript. this mean?
- Includes support for the NodeJS API.
NodeJS API:
- A set of JavaScript libraries that are useful for creating
server programs.
V8 (from Chrome):
- The JavaScript interpreter ("engine") that NodeJS uses
to interpret, compile, and execute JavaScript code
First: Chrome
Chrome:
- A browser written in C++.
- Can interpret and execute JavaScript code.
- Includes support for the DOM APIs.
DOM APIs:
- JavaScript libraries to interact with a web page
V8:
- The JavaScript interpreter ("engine") that Chrome uses
to interpret, compile, and execute JavaScript code
Chrome, V8, DOM
Parser
JavaScript DOM API
Execution
Engine
runtime Implementation
(Call stack,
Garbage memory, etc.)
Collector
Parser
JavaScript DOM API
Execution runtime Implementation
Engine
(Call stack,
Garbage memory, etc.)
Collector
Parser
JavaScript DOM API
Execution runtime Implementation
Engine
(Call stack,
Garbage memory, etc.)
Collector
console.log('V8');
NodeJS, V8, NodeJS APIs
Parser
JavaScript NodeJS API
Execution
Engine
runtime Implementation
(Call stack,
Garbage memory, etc.)
Collector
Parser
JavaScript
NodeJS API
Execution runtime
Engine
(Call stack,
Implementation
Garbage memory, etc.)
Collector
const x = 15;
x++;
"Please execute
http
.createServer()"
Parser
JavaScript NodeJS API
Execution runtime Implementation
Engine
(Call stack,
Garbage memory, etc.)
Collector
http.createServer();
Parser
JavaScript
NodeJS API
Execution runtime
Engine
(Call stack,
Implementation
Garbage memory, etc.)
Collector
document.querySelector('div');
ReferenceError: document is not defined
Parser
JavaScript
NodeJS API
Execution runtime
Engine
(Call stack,
Implementation
Garbage memory, etc.)
Collector
Parser
JavaScript NodeJS API
Execution runtime Implementation
Engine
(Call stack,
Garbage memory, etc.)
Collector
console.log('nodejs');
NodeJS:
- A JavaScript runtime written in C++.
- Can interpret and execute JavaScript.
- Includes support for the NodeJS API.
NodeJS API:
- A set of JavaScript libraries that are useful for creating
server programs.
V8 (from Chrome):
- The JavaScript interpreter ("engine") that NodeJS uses
to interpret, compile, and execute JavaScript code
node command
$ node
> let x = 5;
undefined
> x++
5
> x
6
NodeJS
simple-script.js
function printPoem() {
console.log('Roses are red,');
console.log('Violets are blue,');
console.log('Sugar is sweet,');
console.log('And so are you.');
console.log();
}
printPoem();
printPoem();
node command
$ node simple-script.js
Roses are red,
Violets are blue,
Sugar is sweet,
And so are you.
Server
Emitter.on
http://localhost:portNumber, e.g.
http://localhost:3000
This server
returns the same
response no
matter what the
request is.
Node for servers
app.method(path, handler)
- Specifies how the server should handle HTTP method
requests made to URL/path
- This example is saying:
- When there's a GET request to
http://localhost:3000/hello, respond with the text
"GET hello!"
Handler parameters
fetch()
curl
curl
curl
curl --request
fetch()
fetch()
a different origin:
Enable CORS
Enable CORS
Enable All CORS Requests
const express = require('express’)
const cors = require('cors’)
const app = express()
app.use(cors())
Configuring CORS
const express = require('express’)
const cors = require('cors’)
const app = express()
const corsOptions = {origin: 'http://example.com'}
app.use(cors(corsOptions))
app.post() /hello
fetch()
Changing the fetch()method
fetch()
fetch()
method:
fetch()with POST
Sending data to the server
Route parameters
fetch()
https://api.spotify.com/v1/albums/7aDBFWp72P
z4NZEtVBANi9
7aDBFWp72Pz4NZEtVBANi9
Route parameters
req.params
Route parameters
Route parameters
Query parameters
https://api.spotify.com/v1/search?type=album
&q=beyonce
type album
q beyonce
Query parameters
req.query:
Query params with POST
Query params with POST
POST message body
fetch()
POST message body
body-parser
jsonParser
POST message body
POST message body
req.body
POST message body
req.body
jsonParser
POST message body
fetch()
Recap
GET vs POST
○
○
Route params vs Query params
●
○
○
Example: Spotify API
https://api.spotify.com/v1/albums/7aDBFWp72Pz4NZEtVBA
Ni9
-
https://api.spotify.com/v1/search?type=album&q=the%20we
e knd&limit=10
-
package.json
Installing dependencies
node_modules
Uploading server code
node_modules
node_modules
Managing dependencies
node_modules
npm
npm package.json
package.json
package.json
package.json
$ npm init
package.json
Auto-generated package.json
Saving deps to package.json
$ rm -rf node_modules
$ npm install
npm scripts
$ npm
$ npm start
Improve the simple-blog
Change Posts Structure
Backend:
const BlogPosts = [
{
slug: "first-blog-post",
title: "First Blog Post",
description: "Lorem ipsum dolor sit amet, consectetur
adip.",
},
{
slug: "second-blog-post",
title: "Second Blog Post",
description: "Hello React Router v6",
},
];
module.exports = { BlogPosts };
Add New Post
Backend (index.js):
const express = require("express");
const app = express();
const cors = require("cors");
const BlogPosts = require("./BlogPosts");
const bodyParser = require("body-parser");
const jsonParser = bodyParser.json();
app.use(cors());
Frontend (NewPost.js):
function NewPost() {
const [newPost, setNewPost] = useState("");
const {register,handleSubmit,formState: { errors },} = useForm();
const onSubmit = async (data) => {
const post = JSON.stringify(data);
try {
const response = await fetch("https://qshsfj-8080.csb.app/api/post", {
method: "post", headers: {
'Accept': 'application /json’,
'Content-Type':'application/json’
},
body: post,
});
if (response.ok) setNewPost("Post created successfully!");
} catch (error) {
console.error("Error creating data:", error);
setNewPost("Post created failed!");
}
};
Add New Post
Frontend (NewPost.js):
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div style={{ padding: 10 }}>{" "}<br />
<span>Slug:</span><br />
<input type="text" {...register("slug", { required: true })} /><br />
{errors.slug && <div style={{ color: "red" }}>Slug is required</div>}
<span>Title:</span><br />
<input type="text" {...register("title", { required: true })} /><br />
{errors.title && <div style={{ color: "red" }}>Title is required</div>}
<span>Description:</span><br />
<input type="text" {...register("description", { required: true })} />
<br />
{errors.description && <div style={{color:"red"}}>Description is
required</div>}
<br/><button type="submit">Add New</button>
<p className="text-success">{newPost}</p>
</div>
</form>
);
}
Login
Backend (index.js):
app.post("/api/login", jsonParser, (req, res) => {
const creds = {
username: req.body.username,
password: req.body.password,
};
if (creds.username === "admin" && creds.password === "123")
{
res.status(200)
.send({ message: "Login successful});
} else {
res.status(400).send({ message: "Login failed});
}
});
Login
Frontend (Login.js):
function Login({ onLogin }) {
const [creds, setCreds] = useState({});
const [error, setError] = useState("");
const navigate = useNavigate();
const handleLogin = async () => {
try {
const response = await fetch("https://qshsfj-8080.csb.app/api/login", {
method: "post",headers: {
'Accept': 'application /json’,
'Content-Type':'application/json’
},
body: JSON.stringify(creds),
});
if (response.ok){
onLogin && onLogin({username: creds.username});
navigate('/stats’);
}else setError("Invalid username or password!");
} catch (error) {
console.error("Login error:", error);
setError("Login failed!");
}
}
Login
Frontend (Login.js):
return (
<div style={{ padding: 10 }}> <br/>
<span>Username:</span><br/>
<input type="text" onChange={(e) => setCreds({...creds,
username:e.target.value})}/><br/>
<span>Password:</span><br/>
<input type="password" onChange={(e) =>setCreds({...creds,
password: e.target.value})}/><br/><br/>
<button onClick={handleLogin}>Login</button>
<p>{error}</p>
</div>
);
}
Get Post List And Post Detail
Backend (index.js):
app.get("/api/posts", function (req, res) {
res.send(JSON.stringify(BlogPosts.BlogPosts));
});
Frontend (PostLists.js):
export default function PostLists() {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch("https://qshsfj-8080.csb.app/api/posts”);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);}
const result = await response.json();
setData(result);
setLoading(false);
} catch (error) {
console.error("Error fetching data:", error);
setError("An error occurred while fetching the data.");
setLoading(false);
}
};
fetchData();
}, []);
Get Post List
Frontend (PostLists.js):
return (
<ul>
{data.map((d) => (
<li key={d.slug}>
<Link to={`/posts/${d.slug}`}>
<h3>{d.title}</h3>
</Link>
</li>
))}
</ul>
);
}
Get Post Detail
Frontend (Post.js):
export default function Post() {
const { slug } = useParams();
const [post, setPost] = useState("");
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch("https://qshsfj-
8080.csb.app/api/post/"+slug);
const result = await response.json();
setPost(result);
} catch (error) { console.error("Error fetching data:", error);}
};
fetchData();
}, []);
const { title, description } = post;
return (
<div style={{ padding: 20 }}>
<h3>{title}</h3>
<p>{description}</p>
</div>);
}
Layout and Routes
Frontend (ProtectedRoute.js):
import {Navigate} from "react-router-dom";
return children;
}
function Stats() {
return (
<div style={{ padding: 20 }}>
<h2>Stats View</h2>
<p>Lorem ipsum dolor sit amet, consectetur adip.</p>
</div>
);
}