Connecting-to-our-Database
- Now let's head to the package that we added
config
in thenpm install
command, what it does is that it will look fordefault.json
the file inside config (folder) which we created earlier that will consist of the global variables for our project. - Now let's open that
default.json
file and place the below snippet in it:
{
"mongoURI": "<ConnectionStringHere>"
}
- We'll replace the Connection String from the cluster's string from our Atlas Account (if you still don't have an account, click here to create one)
- After Logging in to the Atlas, create a free Cluster and add a database user in it
- Now use the below code in the
db.js
the file inside the config (folder):
const mongoose = require('mongoose');
const config = require('config');
// Grab the Connection string URL from the default.json file
const db = config.get('mongoURI');
const connectDB = async () => {
try {
await mongoose.connect(db, {
useNewUrlParser: true,
useUnifiedTopology: true
});
console.log('MongoDB Connected');
} catch (err) {
console.log(err.message);
}
}
module.exports = connectDB;
Add the below-given code right below the 3rd line in the index.js file:
- So we're now connected with our Database
Creating a Schema for our Data
- Place the below Schema code into the
Url.js
present in themodels
folder
const mongoose = require('mongoose');
const urlSchema = new mongoose.Schema({
urlCode: String,
longUrl: String,
shortUrl: String,
date: {
type: String,
default: Date.now
},
clicks: {
type: Number,
required: true,
default: 0
}
});
module.exports = mongoose.model('Url', urlSchema);
Setting-up-the-Routes-for-the-app
- So as we created a folder of
routes
earlier, we'll use it store various routes of our app. before that let's link those routes in the mainindex.js
file. - Place the below code in the
index.js
file right before the get('/'----) route:
// Define Routes----------------
// Route-> Redirection
app.use('/', require('./routes/urlRedirect'));
// Route-> Shortening
app.use('/shorten', require('./routes/url'));
Now comes the code part
for the 2 routes:
url.js
const express = require('express');
const router = express.Router();
const validUrl = require('valid-url');
const shortid = require('shortid');
const Url = require('../models/Url');
// @route POST /api/url/shorten
// @desc Create short URL
router.post('/', async (req, res) => {
const longUrlPassed = req.body.longUrl;
const shortUrlPassed = req.body.shortUrl;
const baseUrl = "http://" + req.headers.host;
// Check base url
if (!validUrl.isUri(baseUrl)) {
res.status(401).json('Invalid base url');
}
urlCode = shortid.generate();
if (shortUrlPassed === '') {
// Create url code
} else {
urlCode = shortUrlPassed;
let url = await Url.findOne({
urlCode
});
// If already exisits
if (url) {
// Then redirect to the Home Page
return res.redirect(baseUrl);
}
}
// Check long url
if (validUrl.isUri(longUrlPassed)) {
try {
let url = await Url.findOne({
longUrl: longUrlPassed
});
const shortUrl = baseUrl + '/' + urlCode;
url = new Url({
longUrl: longUrlPassed,
shortUrl,
urlCode
});
await url.save();
return res.redirect(baseUrl);
res.json(url);
} catch (err) {
console.log(err);
res.status(500).json('Server error');
}
} else {
res.status(401).json('Invalid Long url');
}
});
module.exports = router;
urlRedirect.js
const express = require('express');
const router = express.Router();
const Url = require('../models/Url');
// @route GET /:code
// @desc Redirect to long/original URL
router.get('/:code', async (req, res) => {
try {
const url = await Url.findOne({
urlCode: req.params.code
});
if (url) {
url.clicks++;
await url.save();
return res.redirect(url.longUrl);
} else {
return res.status(404).json('No url found');
}
} catch (err) {
console.log(err);
res.status(500).json('Server error');
}
})
module.exports = router;
- Now, let's test the app. Just save the files and open the
localhost:3000
. - When we'll pass some valid URL in the long Url field from the form and then submit the form, then you'll be redirected to the home page only.
- But the catch here is that we can't see the data that we recorded from the form, on our Home page. Though it can be seen from the Atlas Collection.
- So lets now render the URLs shortened. Place the below code into the
index.js
file, just above this lineres.render('home');
inside the Home Page Route. Now the HomePage route looks like this:
// Route-> Home Page
app.use('/', async (req, res) => {
const urls = await Url.find();
res.render('home', {
urls: urls
});
});
- Do add the below statement to make the above
const urls....
statement work:
const Url = require('./models/Url');
- Now let's work on the final part i.e. the Front End
home.ejs
file replace the code of the tables div as below
<div style="margin: auto;" class="row justify-content-md-center table-responsive-sm">
<table style="padding: 0 25px 0 25px;" class="table table-hover col-12 col-md-10 col-lg-6">
<thead>
<tr>
<th># ID</th>
<th>Long URL</th>
<th>Short URL</th>
<th>Clicks</th>
</tr>
</thead>
<tbody>
<% var index = 1; urls.forEach(url => { %>
<tr>
<th scope="row">
<%=index %>
</th>
<td>
<a target="_blank" href="<%= url.longUrl %>">
<%= url.longUrl %>
</a>
</td>
<td>
<a target="_blank" href="<%= url.urlCode %>">
<%= url.urlCode %>
</a>
</td>
<td>
<%= url.clicks %>
</td>
</tr>
<% index+=1; }) %>
</tbody>
</table>
</div>
For the detailed steps follow this Pushing-Project-to-GitHub-and-Azurelink
Thanks for reading this article 😄
Excellent article and this helps to enhance your knowledge regarding new things. Waiting for more updates.
ReplyDeleteAngular Chrome Developer Tools
Angular Developer Tools