-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.js
123 lines (98 loc) · 4.03 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
*************************************************************************************************
Current-C: A SIMPLE CURRENCY CONVERTER APP WITH REAL-TIME DATA & CONVERSIONS
AUTHOUR: RYAN HADLEY (eagleTears)
*************************************************************************************************
This app uses the APILayer API to provide data regarding exchange rates, and quickly converts any of the major world currencies by returning the data within a HTML table.
Please note that this node.js app assumes ES module functionality, so you must ensure "type": "module" is added to package json file.
To make the API request, I have imported 'node-fetch' to allow the JS fetch request method to be used for server-side scripting.
*/
// App setup
import express from "express"
import bodyParser from "body-parser"
import fetch from "node-fetch"
import config from "./config.js"
const app = express()
app.set("view engine", "ejs")
app.use(
bodyParser.urlencoded({
extended: true
})
)
app.use(express.static("public"))
// Insert own API key from APILayer as the value inside this object literal
const myHeaders = {
apikey: config.apikey
}
const requestOptions = {
method: "GET",
redirect: "follow",
headers: myHeaders
}
/*
ERROR HANDLER
Function to handle errors that may occur in the rendering of the results ('conversion') page, or home page due to failure to connect with the API.
It takes an 'error' parameter that is itself the value of any 'catch' function passed in, as well as the 'response' argument.
The latter allows the rendering of the error.ejs page. The error is stored in a var and then rendered on the error page to produce a more accurate, dynamic message.
*/
const handleError = (error, res) => {
const errorMessage = error
console.log(errorMessage)
res.render("error", {
errorMessage: errorMessage
})
}
// Request the list of currencies from the API and render them as dropdown options (home page)
fetch("https://api.apilayer.com/exchangerates_data/symbols", requestOptions)
.then((response) => response.json())
.then((result) => {
console.log("resolved")
const currencyList = result.symbols
app.get("/", (req, res) => {
res.render("index", {
currencyList: currencyList
})
})
})
.catch((error, res) => handleError(error, res))
/*
CONVERSION
Once the user makes a POST request after selecting the currencies to convert, those values are stored and passed into the API conversion endpoint.
When that response is returned, the user's choices and resulting conversion are sent back to them inside a HTML table.
The rendered values of 'rate' and the 'conversion' use the toFixed method in order to reduce the decimals of those variables and make the output cleaner and more readable.
*/
app.post("/", (req, res) => {
const amount = req.body.amount
const fromCurrency = req.body.currency1
const toCurrency = req.body.currency2
fetch(
`https://api.apilayer.com/exchangerates_data/convert?to=${toCurrency}&from=${fromCurrency}&amount=${amount}`,
requestOptions
)
.then((response) => response.json())
.then((result) => {
res.render("conversion", {
amount: amount,
fromCurrency: fromCurrency,
toCurrency: toCurrency,
date: result.date,
rate: result.info.rate.toFixed(2),
conversion: result.result.toFixed(2)
})
})
.catch((error) => handleError(error, res))
})
// Allow user to return home from conversion page to enter another conversion
app.post("/conversion.ejs", (req, res) => {
res.redirect("/")
})
// Redirect user back home if 'Try Again' is clicked on error page
app.post("/error.ejs", (req, res) => {
res.redirect("/")
})
// Allow Heroku to define and set a port, but if none found use my localhost port (3000)
let port = process.env.PORT
if (port == null || port == "") port = 3000
app.listen(port, () => {
console.log(`Server running: Port ${port}`)
})