The task I'm doing is, fetch external API, then save the results to database.
I'm a beginner, I really wanna improve my code, to handle error well, and remove redundant code. The code is working, but I'm bit confused with promise and try-catch. I watched some tutorial, still not sure in the situation which way is better. Anyone could please help me? I really appreciate it!
//app.js
const express = require('express')
const fetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args))
const app = express()
const sqlite3 = require('sqlite3').verbose()
const ExternalAPI = 'https://open.er-api.com/v6/latest'
const db = new sqlite3.Database('currency.db');
const connectDatabase = () => {
return new Promise((resolve, reject) => {
db.on('error', (err) => {
reject(new Error(`Failed to connect to database: ${err.message}`));
});
db.on('open', () => {
console.log('Connected to the currency database.');
resolve(db);
});
});
};
const createTable = (db) => {
return new Promise((resolve, reject) => {
db.run(
`CREATE TABLE IF NOT EXISTS results (
id INTEGER PRIMARY KEY AUTOINCREMENT,
request_at TEXT NOT NULL,
rate_USD REAL NOT NULL,
rate_EUR REAL NOT NULL,
rate_GBP REAL NOT NULL,
rate_CNY REAL NOT NULL
)`,
(err) => {
if (err) reject(new Error(`Failed to create table: ${err.message}`))
else resolve();
}
);
});
};
const connectDatabaseAndTable = async () => {
try {
await connectDatabase();
await createTable();
} catch (err) {
console.error(err);
}
};
const fetchExchangeRates = async () => {
try {
const res = await fetch(ExternalAPI)
const data = await res.json()
return data
} catch (err) {
console.error(err)
throw new Error('Failed to fetch exchange rates')
}
}
const insertExchangeRatesAndTimeIntoDB = async (db, rates) => {
const requestAt = new Date().toLocaleString()
const { USD, EUR, GBP, CNY } = rates
const query = `INSERT INTO results(request_at, rate_USD, rate_EUR, rate_GBP, rate_CNY) VALUES (?,?,?,?,?)`
const params = [requestAt, USD, EUR, GBP, CNY]
try {
return new Promise((resolve, reject) => {
db.run(query, params, (err) => {
if (err) reject(err)
else resolve()
})
})
} catch (err) {
console.error(err)
throw new Error('Failed to insert exchange rates into the database')
}
}
const retrieveExchangeRatesFromDB = async (db) => {
try {
db.all(`SELECT * FROM results`, [], (err, rows) => {
if (err) console.error(err.message);
rows.map((row) => console.log(row))
})
} catch (err) {
console.error(err)
throw new Error('Failed to retrieve exchange rates from the database')
}
}
const closeDB = (db) => {
return new Promise((resolve, reject) => {
db.close((err) => {
if (err) {
console.error(err)
reject(err);
} else resolve()
})
})
}
app.get('/', async (req, res) => {
try {
connectDatabaseAndTable()
const exchangeRates = await fetchExchangeRates()
await insertExchangeRatesAndTimeIntoDB(db, exchangeRates.rates)
const retrievedRates = await retrieveExchangeRatesFromDB(db)
console.log(retrievedRates)
closeDB(db)
res.json({ status: 200, success: true })
} catch (err) {
console.error(err)
res.status(500).send('Something went wrong...')
}
})
module.exports = app
//index.js
const express = require('express')
const app = require('./app')
const PORT = 5005
app.listen(PORT, () => {
console.log(`App is listening on http://localhost:${PORT}`)
})
.get()
opens / closes DB, but remembering that "it's still open" would reduce latency for repeated GETs. Please COMMIT inserts. \$\endgroup\$