Time, Fetch and Deployment
Working with the Date object in JavaScript, fetching data from external APIs, and deploying a Node.js application.
Working with Time in JavaScript
The Date Object
In JavaScript, we can call on the Date object to generate a generic Date.
However, the object is a number in milliseconds since midnight of January 1, 1970 (UTC).
It is like this, to make sure we have a universal and timezone-independent way of calculating time.
Date Methods
To generate a Date object, we can generate it like so:
new Date() // UTC date + time
// 28th of August, 2025, 3.30
// (note that August = 7)
new Date(2025, 7, 28, 3, 30)
Date() // Local time string
Date.now() // Unix timestamp
// (ms since Jan 1, 1970)Getting Current Month
When we call on the Date.getMonth() method, it returns a numbers,
representing the index in an array of 12 Months, starting at January - which means to access
April, we call upon monthNames[3].
// Manual array approach
const monthNames = [
"January", "February", "March",
"April", "May", "June", "July",
"August", "September", "October",
"November", "December"
];
app.get('/months/v1', (req, res) => {
// 0-11
const today = new Date().getMonth();
res.send(monthNames[today]);
});
If we don't have a hardcoded array of month names, we can call on the method toLocaleString().
// Using toLocaleString
app.get('/months/v2', (req, res) => {
const currentMonth = new Date()
.toLocaleString('en-uk', { month: 'long' });
res.send({ data: currentMonth });
});Unix Timestamp Counter
In an assignement with the dogma "Time", I created a new epoch for the unix counter, dated at my son's birth.
In order to do so, I had to first generate a Date object, then in a function make const elapsedTimeUnix,
which I then updated every second with setInterval() to generate a counter.
const newUnix = new Date(2025, 7, 28, 3, 30).getTime();
function getTimeSinceBirthInUnix() {
const elapsedTimeUnix = Math.floor(
(Date.now() - newUnix) / 1000
);
unixCounter.textContent = elapsedTimeUnix;
}
// Updates every second
setInterval(getTimeSinceBirthInUnix, 1000);
Fetch API
Introduction to Fetch
In our frontend, we can utilize the fetch() method, for making HTTP requests to our server and process
the responses.
The metod starts the process of fetching a resource from a network, which then returns a promise, that gets fulfilled once the response is available.
Handling Responses
When requesting a resource, we expect a response from the server, that's where the .then() method comes in
When the promise has been resolved, .then() takes the raw response and calls .json(),
which parses it to a JSON string - this also returns a promise, which is why there is a second .then().
The second .then() recieves the parsed JavaScript object (data) and logs it to the console.
Basic Fetch Request
fetch('/movies')
.then(response => response.json())
.then(data => console.log(data));POST Request
If you do not set a HTTP-verb for the method, it will default to GET, however, you can use
the method: option to use a different type of request.
After defining the verb, you can set the headers and then the body, which is the actual payload of the request.
This is very useful when we want to send data to a server, in this instance we want to send a
JSON object, containing a Movie.
fetch('/movies', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
title: 'New Movie',
description: 'Description'
})
})
.then(res => res.json())
.then(data => console.log(data));
JavaScript and HTML Integration
The Document Object Model (DOM)
The DOM (Document Object Model) is an API that represents the HTML page as a tree of objects - we can use JavaScript to access these objects and modify them in memory. The DOM tree consists of nodes, where each of these nodes represents a part of the document.
The DOM is not part of the JavaScript language - it was designed to be independent of any language, and therefore we can theoretically use any langauge to access it, since it is available from a single API.
DOM Manipulation In Practice
In this example, JavaScript updates the text inside an HTML element, whenever the function runs, meaning that the page can change, without it being reloaded.
document represents the HTML page - but the .getElementById() is a DOM method, which finds and returns the HTML element
with the given id.
DOM Manipulation In Practice
const counter =
document.getElementById('guest-book-counter');
let counterValue = 0;
function incrementCounter() {
counter.textContent = ++counterValue;
}Event Handling
The incrementCounter function demonstrates how to update DOM elements dynamically, typically triggered by user events.
JavaScript Loading
Now that we know we can manipulate the DOM, we need to load the script.
This can be done two ways: Inline or External.
The first example, is using Inline. This can be fine for small or few lines of scripts since it is laoded directly into the HTML file.
Second example is by calling upon a JavaScript file - this is great when we have a bunch of logic, which we then can divide into separate modules or files, granting us with a better overview of scripting. We are required to think more about our architecural decision in our project, but granted that, we have improved maintainability and readability by moving it into an external script.
// Inline (avoid mixing)
<script> /* code */ </script>
// External (preferred)
<script src="./frontpage.js"></script>Server Setup and Error Handling
Previously, when we have set up a server in our Node.js backend, we did it by only using app.listen(8080).
While this can be fine, it can be better to have a more verbose method, not only telling us if the server is running, but also if the server failed to start, giving us a much faster failure response.
To do so, we need to create a callback function to app.listen, and parse error
as a paramter to the function. If something goes wrong, the error object will contain information about the problem.
Inside the callback, if error exists, we log an error - if not, we log that the Server is running on port 8080
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.sendFile(
__dirname + '/public/frontpage.html'
);
});
app.listen(8080, (error) => {
if (error) {
console.log('Error starting the server');
return;
}
console.log('Server is running on port', 8080);
});
Error Handling and Validation
Falsy Values
JavaScript treats these as false in conditionals:
falsenullundefinedNaN(not a number)""(empty string)0
Truthy Checks in Practice
if (error) { // Truthy check
console.log('Error occurred');
return;
}Deployment
Whenever we are developing an app, when we want to access it, it can only run on localhost.
We might want to make that publicly available, and that's where deployment comes in.
There are several ways of deploying an application, ranging from incredibly simple to very advanced, depending on what you need.
Is it a single static page with no database? Use Vercel or GitHub Pages. Are you deploying a full-scale application with many microservices and high user load? Use a cloud provider like AWS, Azure, or orchestrate containers with Docker and Kubernetes.
Simple Deployment With Vercel
However, so far we have only made small applications without databases or any complex infrastructure, which makes Vercel a great fit. Vercel is a cloud platform that lets us deploy Node.js and frontend projects with minimal configuration, it utilizes serverless computing, which means it will only spin up a VM, when there is a request for the page.
To deploy with Vercel, we can register at their website, connect our GitHub account and deploy within minutes.
Vercel integrates really well with GitHub, which means that pushing to a repository can automatically trigger a new deployment, so every time we push new code, our live site updates as well.