Fetching data from mongoDB and displaying on HTML - html

I'm having trouble understanding how to fetch data from the MongoDB database and display it on HTML. I already have set for the data.
this is the the server.js file.
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser')
const mongoose = require('mongoose');
const app = express();
//map global promise - get rid of warning
mongoose.Promise = global.Promise;
// connect to mongoose
mongoose.connect('mongodb://localhost/peppino-calc', {
useMongoClient: true
})
.then(() => { console.log('MongoDB connected...')})
.catch(err => console.log(err));
//Load salaryModel
require('./modles/Idea.js');
const Idea = mongoose.model('ideas');
//body parser middleware
app.use(bodyParser.urlencoded({extended: false}))
app.use(bodyParser.json())
// post history page
app.get('/history', (req, res) => {
Idea.find({})
.sort({date:'desc'})
res.sendFile(__dirname + '/js/newJs/history.html')
})
//process form
app.post('/ideas', (req, res) => {
let errors = [];
if(errors.length > 0) {
console.log(errors[0]);
} else {
const newUser = {
amount: req.body.totalamount,
hours: req.body.totalhours,
salary: req.body.totalsalary,
tip: req.body.totaltip,
date: req.body.datetotal
}
new Idea(newUser)
.save()
.then(idea => {
res.redirect('/history');
})
}
});
app.use(express.static(path.join(__dirname, './js/newJs')));
app.set('port', process.env.PORT || 5700);
var server = app.listen(app.get('port'), function() {
console.log('listening on port ', server.address().port);
});
my goal is to display the data from the database in a specific html page.
any help?

You have to use a template engine in order to display data in an html page, there are many template engines, you can choose one from this link
Here is an example using pug:
1- install pug
npm install pug --save
2- set view directory:
app.set('views', path.join(__dirname, 'views'));
3- set pug as the default view engine
app.set('view engine', 'pug');
4- create history.pug inside views folder
doctype html
html
head
body
table
thead
tr
th Name
th date
tbody
each idea in ideas
tr
td= idea.name
td= idea.date
5- pass data from express to pug:
app.get('/history', (req, res) => {
let ideas = Idea.find({})
.sort({date:'desc'}).exec( (err, ideas) => {
res.render('history', ideas);
});
})

Related

How to render to Dom API Array from res.json?

I got some data (articles) from website after scraping with cheerio. I can see it as json file on terminal.
How can I render it to Dom? How can get to see it on the console on the browser?
It's a simple app with only index.js file and at the moment.
Thanks!
I have console log it to terminal like so:
res.json(articles);
console.log(articles)
index.js looks like this:
const PORT = process.env.PORT || 8000;
const express = require("express");
const axios = require("axios");
const cheerio = require("cheerio");
const app = express();
const webpages = [{
name: "ynet",
address: "https://www.ynet.co.il/sport/worldsoccer",
}]
const articles = [];
webpages.forEach(webpage => {
axios
.get(webpage.address)
.then((res) => {
const html = res.data
const $ = cheerio.load(html)
$('div.slotView', html).each(function () {
const title = $(this).text();
const url = $(this).find('a').attr("href");
const img = $(this).find('img').attr('src')
articles.push({
title,
url,
img,
source: webpage.name
});
});
}).catch((err) => console.log(err));
});
app.get("/", (req, res) => {
res.json(articles);
console.log(articles)
})
app.listen(PORT, () => {
console.log(`server runnig on PORT ${PORT}`);
});
I have added an app.js file, querySelector the id from div HTML file, and fetched it like so:
const ynet = document.querySelector('#ynet');
fetch('http://localhost:8000/ynet')
.then(response => response.json())
.then(data => {
data.forEach(element => {
const item = `<a href = "${element.url}" target="_blank"><div class="wrapper"><h3>` +
element.source +
`</h3><p class="text">` +
element.title +
`<img src="${element.img}" alt=""></p></div ></a>`
ynet.insertAdjacentHTML("beforeend", item)
});
console.log(data)
})
.catch(err => {
console.log(err)
})

How to render html code stored as string?

Hi I am trying to send the contents of string stored in mongo db through res.render. However, if I check after sending this string, the tag appears in the form of a string and does not appear in html, so I want to know how to solve it.
router.get("/:id", async function (req, res) {
var article = await Article.findById(req.params.id);
console.log(article);
res.setHeader("Content-type", "text/html");
res.render("articles/article", { article: article });
});
article = "<p>내용입니다.</p>"
here is the working example. You have to install the pug template engine or any other template engine. See the test. pug file and note that if the variable is HTML content then we have to use the syntax "!{para}" or if the variable is a simple string then we can use the syntax "#{para}".
so the folder structure would be like
app.js
views ->test.pug
// app.js file
var express = require('express');
var app = express();
var PORT = 3000;
app.set('view engine', 'pug');
app.use('/', function(req, res, next){
res.render('test', {para : `<p>This is paragraph</p>`});
});
app.listen(PORT, function(err){
if (err) console.log(err);
console.log("Server listening on PORT", PORT);
});
// html file test.pug
<div>!{para}</div>

Posting API data to ejs using node-fetch

I have been having trouble with displaying the API information that I fetched using node-fetch. I want the data title, img, and etc to show in the ejs body, but I receive an error message from index.ejs saying currentData is not defined.
var express = require('express');
var fetch = require('node-fetch');
var app = express();
//Port information
const port = process.env.port || 3000;
//tell application to use ejs for templates
app.set('view engine', 'ejs');
//make styles public
app.use(express.static("public"));
app.get('/', function(req,res){
//return something to homepage
res.render('index');
});
app.get('/comic', function(req,res){
let currentData;
fetch('http://xkcd.com/info.0.json')
.then(res => res.json())
.then(data => {
curentData = data;
res.json(currentData);
});
});
//index.ejs file:
<div>
<form action ="/dailyInfo" method="POST">
<%= currentData.month %>
</div>

How to add a users auth in feathers middleware?

I use feathersjs framework in my projekt. In older version my middleware it was work but afer update a framework and after created new app with authenticate a middleware not working.
My index.js file show like below:
const cookieParser = require('cookie-parser');
const { authenticate } = require('#feathersjs/express');
module.exports = function (app) {
app.get('/login', (req, res) => {
res.sender('login');
});
app.use('/', cookieParser(), authenticate('jwt'), async (req, res) => {
const { user } = req;
try {
await app.service('users').get(user._id);
res.sender('home');
} catch(e){
res.redirect('/login');
}
});
}
I have a login script in jQuery like below:
$(document).ready(function(){
const socket = io();
const app = feathers();
app.configure(feathers.socketio(socket));
app.configure(feathers.authentication({
storage: window.localStorage
}));
$('.form-signin').submit(function(){
app.authenticate({
strategy: 'local',
username: $('#inputUsername').val(),
password: $('#inputPassword').val(),
}).then( result => {
document.cookie = "feathers-jwt=" + result.accessToken;
window.location.href = "/";
}).catch(error => {});
});
});
My problem is when I click a login button with a data correctly I receive an accessToken but I can't see home page and app show me every time 401 error code - not authorization with.
An console shows me this info: info: Invalid authentication information (no `strategy` set) {"type":"FeathersError","name":"NotAuthenticated","code":401,"className":"not-authenticated","errors":{}}
In new version not working too failureRedirect: '/login'
SOLUTION
Add below code before app.get('/', authenticate('jwt'), (req, res) => {});
app.use('/', cookieParser(), (req, res, next) => {
var cookies = req.cookies;
var token = cookies['feathers-jwt'];
req.authentication = {
strategy: 'jwt',
accessToken: token
}
next();
})

Best practices for MySQL + Node/Express + Angular Stack

I am currently using MySQL for the db instead of the popular mongodb, since that is the case there isn't much documentation out there as far as architecture and getting set up. This is my current structure
client
-- angular files
routes
-- index.js
views
-- 404 page
app.js
I don't understand how I can implement controllers or models into this structure. I'm currently grabbing data from the db or sending it with the routes..I'm not sure what the added layer of controllers would do. Maybe this is a dumb question but I would just like to have a clear baseline so that my project will scale well. I feel like there should be way more to this than what I currently have.
index.js
const express = require('express');
const mysql = require('mysql');
const router = express.Router();
const db = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'password',
database : 'db'
});
// Connect
db.connect((err) => {
if(err){
throw err;
}
console.log('MySql Connected...');
});
// Select Data
router.get('/getData', (req, res) => {
let sql = 'SELECT * FROM data';
let query = db.query(sql, (err, results) => {
if(err) throw err;
console.log(results);
res.send(results)
});
});
module.exports = router;
app.js
const express = require('express');
const mysql = require('mysql');
const bodyParser = require('body-parser');
const path = require('path');
const cors = require('cors');
const compression = require('compression');
const helmet = require('helmet')
const expressSanitizer = require('express-sanitizer');
const index = require('./routes/index');
const app = express();
const port = 3000;
var corsOptions = {
origin: 'http://localhost:8100',
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}
// var logger = (req, res, next) => {
// console.log('logging...')
// next();
// }
//added security
app.use(helmet())
// //set logger
// app.use(logger)
//cors options
app.use(cors(corsOptions))
//body parser middleware
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: false}))
// Mount express-sanitizer here
app.use(expressSanitizer()); // this line follows bodyParser() instantiations
//set static path
app.use(express.static(path.join(__dirname, 'client')));
// set our default template engine to "ejs"
// which prevents the need for using file extensions
app.set('view engine', 'ejs');
//gzip compression
app.use(compression())
//set views for error and 404 pages
app.set('views', path.join(__dirname, 'views'));
app.use('/', index);
app.use('/fp/trips', trips);
app.listen(port, () => {
console.log('server started on port 3000')
})
When working on Node apps I tend to favor a scheme where controllers are (almost) services -- I think it works really well for small applications.
This is an example:
index.js
let app = express()
let users = require('./services/users')
app.get('/users/:id', async function(req, res, next) => {
try {
res.json(users.getByid(req.params.id))
} catch() {
next(err)
}
})
app.listen(8080)
services/users.js
let db = require('./db')
async function getById(id) {
let conn = await db.connect()
let user = conn.query('SELECT * FROM user WHERE id = ?', [id])
if (!user) {
throw new Error("404")
}
return user
}
module.exports = {getById}
services/db.js
let realDb = require('some-open-source-library-to-interact-with-db')
realDb.initialize(process.env.DB_CREDENTIALS) // pseudo-code here
module.exports = realDb
This though, won't work well when you're building large, complex apps -- I think you will require more structure in that case.
PS: I wouldn't suggest to build a large, complex app ever -- split it into smaller ones where patterns like the one I presented work nicely.
You can use Sequelize as ORM (Object Relational Mapper) for your MySQL DB to make your code more readable and to allow you to create better structure of your app. It also has support for PostgreSQL, MySQL, MariaDB, SQLite, and MSSQL.
There are samples out there how to integrate Sequelize with Express. I'm not sure if I'm allowed to post a github repository here but here it is:
https://github.com/jpotts18/mean-stack-relational
PS. I don't own this repository but this might help you somehow.