NodeJS Mongoose insert event to public/index.html - node.js

I'm learning nodejs and I have a project where I want users to post form data which then populates an html table located in public/index.html.
At the moment, I am writing the submitted data to a database collection using the following code:
const mongoose = require('mongoose')
const express = require('express');
const app = express();
const server = app.listen(3000);
app.use(express.json()); // for retrieving form data
app.use(express.static('public'));
mongoose.connect('mongodb://localhost/class', {useNewUrlParser: true})
.then( () => console.log('Connected to class database'))
.catch( () => console.error('Connection attempt to class database failed'))
const personSchema = new mongoose.Schema({
name: String,
date: {type: Date, default: Date.now}
})
const Person = mongoose.model('Person', personSchema)
app.post('/join_class', (req,res) => {
res.send('... joining class')
console.debug(req.body.name)
// document.getElementById('class_table').insertRow(req.body.name)
joinClass(req.body)
})
async function joinClass(data){
console.log(data)
person = new Person({
name: data.name
})
await person.save();
}
My problem is I need the same data to populate an HTML table located in my public/index.html but of course I don't have access to the document object in index.js. The index.html file is below:
<!DOCTYPE html>
<html lang="en">
<head>
<script src='https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.dev.js'></script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- <script src="/client.js"></script> -->
<title>TestING</title>
</head>
<body>
<table id='class_table'>
<tr><th>Class</th></tr>
<tr><td>testing</td></tr>
</table>
</body>
</html>
So, how can I create a mongoDB event/alert such that when the post data is inserted into the database, the same data is made available to index.html where I CAN use the document object to populate the table?

Here's a example in which you can add new Person's and the list in the index.html page should update on a successful insert.
index.js
app.post('/join_class', (req, res) => {
var person = new Person({
name: req.body.name
});
person.save().then((data) => {
res.send(data);
}).catch((err) => {
res.status(500).send(err);
});
})
app.get('/class', (req, res) => {
Person.find({}).then((data) => {
res.send(data);
}).catch((err) => {
res.status(500).send(err);
});
})
index.html (body tag content)
<body>
<div>
Name:<br>
<input type="text" id="name" value="">
<br>
<button onclick="addPerson()">Add Person</button>
</div>
<br/>
<b>Person's in List: </b>
<ul id='class_table'>
</ul>
<script src="/client.js"></script>
</body>
client.js
function listPerson() {
var req = new XMLHttpRequest();
req.open("GET", '/class');
req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
req.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var aList = JSON.parse(req.responseText),
list = document.getElementById("class_table");
list.innerHTML = "";
aList.forEach(e => {
var item = document.createElement("li");
item.innerHTML = e.name;
list.appendChild(item);
});
}
};
req.send();
}
function addPerson() {
var req = new XMLHttpRequest();
req.open("POST", '/join_class');
req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
req.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) { listPerson(); } //Get list of Person on completion
};
var sName = document.getElementById("name").value;
req.send(JSON.stringify({ "name": sName }));
}
//Initially load a list of Person's
listPerson();

Related

Why do I have to refresh the page in order to connect to the peer system?

I am trying to create an app that allow users to create a videochat event room (by inserting it into the backend's database) and then let other users that have an account on the website to join it. At the moment, the login part is not created, but it is not a problem.
The backend is done in Spring Boot RestAPI (and runs on 8080) and the frontend in nodejs (and runs on 3000). The Peer To Peer system is done using an nodejs server and Peer.js API (and runs on 3001).
The main question is the following:
When the user clicks on an event fetched from the DB, if it is the first one, it becomes host. If not, then it becomes a simple user. When a user enters the room, the host have to refresh the page(like to reconnect to the room) and so does the user, in order to be both connected. Why is so? I will give you the files codes bellow.
The second one: Why this system is not working for Safari and, if it works how to solve it?
server.js:
const express = require('express')
const app = express()
const server = require('http').Server(app)
const io = require('socket.io')(server)
const { v4: uuidV4 } = require('uuid')
app.set('view engine', 'ejs')
app.use(express.static('public'))
app.get('/', (req, res) => {
var http = require("http")
// BELOW IT IS THE BACKEND CONNECTION. TO TEST YOUR CODE, YOU NEED AN ARRAY THAT HAVE ARRAYS WITH sessionID AND name PARAMS LIKE SO: [{"sessionID":"1231", "name":"event"},{...}].
http.get("http://localhost:8080/events", (resp) => {
let data = "";
resp.on("data", (chunk) => {
data += chunk;
});
resp.on("end", () => {
console.log(data);
res.render('index', {events: data})
});
})
.on("error", (err) => {
console.log("Error: " + err.message);
});
})
app.get('/join', (req, res) => {
res.render('join')
})
app.get('/event', (req, res) => {
res.redirect(`/${uuidV4()}`)
})
app.get('/:room', (req, res) => {
res.render('room', { roomId: req.params.room })
})
io.on('connection', socket => {
socket.on('join-room', (roomId, userId) => {
console.log("User connected: " + userId)
socket.join(roomId)
socket.to(roomId).broadcast.emit('user-connected', userId)
socket.on('disconnect', () => {
socket.to(roomId).broadcast.emit('user-disconnected', userId)
})
})
})
server.listen(3000)
script.js:
const socket = io('/')
const videoGrid = document.getElementById('video-grid')
const myPeer = new Peer(undefined, { // user id
host: '/', // path to event
port: '3001' // post
})
const myVideo = document.createElement('video')
myVideo.muted = true
const peers = {}
navigator.mediaDevices.getUserMedia({
video: true,
audio: true
}).then(stream => {
addVideoStream(myVideo, stream)
myPeer.on('call', call => {
call.answer(stream) // HOST SEE OTHERS
const video = document.createElement('video')
call.on('stream', userVideoStream => { // OTHERS SEE HOST
addVideoStream(video, userVideoStream)
})
})
socket.on('user-connected', userId => {
connectToNewUser(userId, stream)
console.log(peers);
})
})
socket.on('user-disconnected', userId => {
if (peers[userId]) peers[userId].close()
})
myPeer.on('open', id => {
socket.emit('join-room', ROOM_ID, id)
})
function connectToNewUser(userId, stream) {
const call = myPeer.call(userId, stream)
const video = document.createElement('video')
call.on('stream', userVideoStream => {
addVideoStream(video, userVideoStream)
})
call.on('close', () => {
video.remove()
})
peers[userId] = call
}
function addVideoStream(video, stream) {
video.srcObject = stream
video.addEventListener('loadedmetadata', () => {
video.play()
})
videoGrid.append(video)
}
room.ejs:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Template</title>
<script>
const ROOM_ID = "<%= roomId %>"
</script>
<script src="https://unpkg.com/peerjs#1.3.1/dist/peerjs.min.js" defer></script>
<script src="/socket.io/socket.io.js" defer></script>
<script src="script.js" defer></script>
<style>
#video-grid{
display: grid;
grid-template-columns: repeat(auto-fill, 300px);
grid-auto-rows: 300px;
}
video{
width: 100%;
height: 100%;
object-fit: cover;
}
</style>
</head>
<body>
<div id="video-grid">
</div>
</body>
</html>
index.ejs:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>index</title>
<script>
var raw = "<%= events %>"
raw = raw.replaceAll(""", "\"") // DONE BECAUSE WHEN PASSING THE PARAM, INSTEAD OF " IT IS THE " ENTITY
var events = JSON.parse(raw)
window.onload = (event) => {
var table = document.querySelectorAll("#events")[0];
table.innerHTML = '';
for (let index = 0; index < events.length; index++) {
table.innerHTML += "<tr><td><a href='/" + events[index].sessionID + "'>" + events[index].name + "</a></td></tr>"
}
};
</script>
</head>
<body>
<h1>Create Event</h1>
<table id="events">
</table>
</body>
</html>

Need Help.Node.Js With Ajax and MongoDB CRUD Working slowly

When I try to add or delete from my database it takes a few seconds for the page to update. I use AJAX and it is still very slow. I can not figure out what the problem is. I am new at NODE JS I came from MVC NET. Thanks and here is my code.
app.js
let express = require('express');
let app = express();
let mongodb=require('./mongodb')
let bodyParser = require('body-parser');
let index=require('./index');
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(bodyParser.json());
app.set('view engine', 'ejs');
app.use(express.static(__dirname + '/public'));
app.listen(8080, function () {
console.log('Example app listening on port 8080!');
});
app.use('/',index);
app.use('/mongo',mongodb);
mongodb.js
let express = require('express');
let MongoClient = require('mongodb').MongoClient;
let url = "mongodb://localhost:27017/";
let router = express.Router();
let obj = null;
router.get('/', function (req, res) {
getDfroMongo(res);
});
function getDfroMongo(res) {
MongoClient.connect(url, function (err, db) {
if (err) throw err;
var dbo = db.db("mydb");
//Sort the result by name:
var sort = { car: 1 };
dbo.collection("customers").find().sort(sort).toArray(function (err, result) {
if (err) throw err;
obj = result;
// db.close();
res.render(__dirname + '/views/mongo', { result: obj });
});
});
}
router.post('/', function (req, response) {
switch (req.body.data) {
case "add":
let car = req.body.car;
let model = req.body.model;
let year = req.body.year;
let myimg = req.body.img;
obj = { car: car, model: model, year: year, img: myimg };
if (car != "" && model != "" && year != "" && myimg != "") {
console.log(obj);
MongoClient.connect(url, function (err, db) {
if (err) throw err;
var dbo = db.db("mydb");
var myobj = { Car: car, Model: model, Year: year, img: myimg };
dbo.collection("customers").insertOne(myobj, function (err, res) {
if (err) throw err;
console.log("1 document inserted");
// db.close();
getDfroMongo(response);
});
});
}
else
console.log('field missed');
break;
case "delete":
let carName = req.body.carName;
MongoClient.connect(url, function (err, db) {
if (err) throw err;
var dbo = db.db("mydb");
var myquery = { Car: carName };
dbo.collection("customers").deleteOne(myquery, function (err, obj) {
if (err) throw err;
console.log("1 document deleted");
// db.close();
getDfroMongo(response);
});
});
break;
case "update":
upcar = req.body.car;
upmodel = req.body.model;
upyear = req.body.year;
upimg = req.body.img;
upcarName = req.body.carName;
// obj = { car: upcar, model: upmodel, year: upyear, img: upimg, carName: upcarName };
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("mydb");
var myquery = { Car: upcarName };
var newvalues = { $set: { Car: upcar, Model: upmodel,Year:upyear,img:upimg } };
dbo.collection("customers").updateOne(myquery, newvalues, function(err, res) {
if (err) throw err;
console.log("1 document updated");
// db.close();
getDfroMongo(response);
});
});
break;
default:
break;
}
});
module.exports=router;
And This Is My View-mongo.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="/css/style.css" rel="stylesheet" type="text/css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<%include title%>
</head>
<body>
<button type="button" name="addDB" id="addDB" onclick="AddDbFunction()">insert</button>
<input type="text" name="car" id="car" placeholder="car">
<input type="text" name="model" id="model" placeholder="model">
<input type="text" name="year" id="year" placeholder="year">
<input type="text" name="img" id="img" placeholder="img"><br>
<button type="button" name="update" id="update" onclick="updateFunction()">update</button>
<button type="button" name="delete" id="delete" id="delete" onclick="deleteFunction()">delete</button>
<input type="text" name="carName" id="carName" placeholder="carName">
<script>
function updateFunction() {
let car = document.getElementById("car").value;
let model = document.getElementById("model").value;
let year = document.getElementById("year").value;
let img = document.getElementById("img").value;
let carName = document.getElementById("carName").value;
let parameters= { data: "update", car: car, model: model, year: year, img: img, carName: carName };
$.ajax({
url: '/mongo',
type: 'POST',
data: parameters,
success: function () {
location.reload();
}
});
}
function deleteFunction() {
let carName = document.getElementById("carName").value;
// $.post('/', { data: "delete", carName: carName });
let parameters = { data: "delete", carName: carName };
$.ajax({
url: '/mongo',
type: 'POST',
data: parameters,
success: function () {
location.reload();
}
});
}
function AddDbFunction() {
let car = document.getElementById("car").value;
let model = document.getElementById("model").value;
let year = document.getElementById("year").value;
let img = document.getElementById("img").value;
// $.post('/', { data: "add", car: car, model: model, year: year, img: img });
let parameters = { data: "add", car: car, model: model, year: year, img: img }
$.ajax({
url: '/mongo',
type: 'POST',
data: parameters,
success: function () {
location.reload();
}
});
}
</script>
<table>
<tr>
<th>Car</th>
<th>Model</th>
<th>Year</th>
<th>image</th>
<!-- <th>id</th> -->
</tr><br>
<% for(let i=0; i < result.length; i++) { %>
<tr>
<td><%= result[i].Car%></td>
<td><%= result[i].Model%></td>
<td><%= result[i].Year%></td>
<!-- <td><%= result[i]._id%></td> -->
<td> <img src="\images\<%= result[i].img%> " width="80" height="80"></td><br>
</tr>
<% } %>
</table>
</body>
</html>
thanks this is greate place!!
Don't connect mongo for each request, just connect once at the start of your script.

koa and sse, the messages are delayed

I have a cpu intensive task on the server, while its running I want to tell the client of the progress to have a good user experience, I looked into SSE using koa-sse-stream, my problem as stated in the question the client is getting all the message at the end of the response which is wrong, the messages must arrive as they are produced.
/event route handler:
import { isObject } from 'util';
import koarouter from 'koa-router';
import koasse from 'koa-sse-stream';
import ipc from 'node-ipc';
ipc.config.maxRetries = 1;
ipc.config.stopRetrying = true;
ipc.config.retry = false;
ipc.config.appspace = 'alerts_event';
ipc.config.silent = true;
const router = new koarouter();
router.get(
'/event',
koasse(),
async (ctx, next) => {
const { client_id } = ctx.state;
// const sse = new SimpleSSE(ctx, false);
let resolver: () => void;
const p = new Promise(res => {
resolver = res;
});
ipc.serve(client_id, () => {
ipc.server.on('message', (data, socket) => {
if (isObject(data)) {
ctx.sse.send(data);
}
});
ipc.server.on('socket.disconnected', _ => {
ctx.sse.end();
resolver();
});
});
ipc.server.start();
await p;
ipc.server.stop();
await next();
},
async ctx => {
console.log(ctx.res.getHeaders());
},
);
export default router;
client html:
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<h6 id="display"></h6>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
const display = document.getElementById('display');
const es = new EventSource('/alerts/v1/event');
es.onmessage = msg => {
console.log('got message from server');
console.log(msg);
display.innerHTML = msg.data;
};
es.onerror = err => {
console.log('got error');
console.log(err);
};
axios({
method: 'get',
url: 'http://localhost:4001/alerts/v1/xlsx',
})
.then(data => {
console.log(data);
es.close();
})
.catch(err => console.log(err));
</script>
</body>
</html>
The problem was with the promise that I wait for to resolve it stopped koa-sse-stream from piping its stream to ctx.body. Once I remove it everything worked as expected.

How to insert and retrieve video from mongodb in node js

I new to mean stack. I want to upload video to mongodb and then I want to retrieve it.
this is app.js file
`const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const crypto = require('crypto');
const mongoose = require('mongoose');
const multer = require('multer');
const GridFsStorage = require('multer-gridfs-storage');
const Grid = require('gridfs-stream');
const methodOverride = require('method-override');
const app = express();
// Middleware
app.use(bodyParser.json());
app.use(methodOverride('_method'));
app.set('view engine', 'ejs');
// Mongo URI
const mongoURI = 'mongodb://fawad:Fawad123#ds155243.mlab.com:55243/imageupload';
// Create mongo connection
const conn = mongoose.createConnection(mongoURI);
// Init gfs
let gfs;
conn.once('open', () => {
// Init stream
gfs = Grid(conn.db, mongoose.mongo);
gfs.collection('uploads');
});
// Create storage engine
const storage = new GridFsStorage({
url: mongoURI,
file: (req, file) => {
return new Promise((resolve, reject) => {
crypto.randomBytes(16, (err, buf) => {
if (err) {
return reject(err);
}
const filename = buf.toString('hex') + path.extname(file.originalname);
const fileInfo = {
filename: filename,
bucketName: 'uploads'
};
resolve(fileInfo);
});
});
}
});
const upload = multer({ storage });
// #route GET /
// #desc Loads form
app.get('/', (req, res) => {
gfs.files.find().toArray((err, files) => {
// Check if files
if (!files || files.length === 0) {
res.render('index', { files: false });
} else {
files.map(file => {
if (
file.contentType === 'video/mp4' ||
file.contentType === 'video/webm '
) {
file.isVideo = true;
} else {
file.isVideo = false;
}
});
res.render('index', { files: files });
}
});
});
// #route POST /upload
// #desc Uploads file to DB
app.post('/upload', upload.single('file'), (req, res) => {
// res.json({ file: req.file });
res.redirect('/');
});
// #route GET /files
// #desc Display all files in JSON
app.get('/files', (req, res) => {
gfs.files.find().toArray((err, files) => {
// Check if files
if (!files || files.length === 0) {
return res.status(404).json({
err: 'No files exist'
});
}
// Files exist
return res.json(files);
});
});
// #route GET /files/:filename
// #desc Display single file object
app.get('/files/:filename', (req, res) => {
gfs.files.findOne({ filename: req.params.filename }, (err, file) => {
// Check if file
if (!file || file.length === 0) {
return res.status(404).json({
err: 'No file exists'
});
}
// File exists
return res.json(file);
});
});
// #route GET /image/:filename
// #desc Display Image
app.get('/video/:filename', (req, res) => {
gfs.files.findOne({ filename: req.params.filename }, (err, file) => {
// Check if file
if (!file || file.length === 0) {
return res.status(404).json({
err: 'No file exists'
});
}
// Check if image
if (file.contentType === 'video/mp4' || file.contentType === 'video/webm') {
// Read output to browser
const readstream = gfs.createReadStream(file.filename);
readstream.pipe(res);
} else {
res.status(404).json({
err: 'Not an image'
});
}
});
});
// #route DELETE /files/:id
// #desc Delete file
app.delete('/files/:id', (req, res) => {
gfs.remove({ _id: req.params.id, root: 'uploads' }, (err, gridStore) => {
if (err) {
return res.status(404).json({ err: err });
}
res.redirect('/');
});
});
const port = 9000;
app.listen(port, () => console.log(`Server started on port ${port}`));
`
index.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous">
<style>
video {
width: 100%;
}
</style>
<title>Mongo File Uploads</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-6 m-auto">
<h1 class="text-center display-4 my-4">Mongo File Uploads</h1>
<form action="/upload" method="POST" enctype="multipart/form-data">
<div class="custom-file mb-3">
<input type="file" name="file" id="file" class="custom-file-input">
<label for="file" class="custom-file-label">Choose File</label>
</div>
<input type="submit" value="Submit" class="btn btn-primary btn-block">
</form>
<hr>
<% if(files){ %>
<% files.forEach(function(file) { %>
<div class="card card-body mb-3">
<% if(file.isVideo) { %>
<video src="video/<%= file.filename %>" alt="">
<% } else { %>
<%= file.filename %>
<% } %>
<form method="POST" action="/files/<%= file._id %>?_method=DELETE">
<button class="btn btn-danger btn-block mt-4">Delete</button>
</form>
</div>
<% }) %>
<% } else { %>
<p>No files to show</p>
<% } %>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"></script>
</body>
</html>
this code work for image..when I used (file.contentType = image/png).
but for video it's not working.. is Image and video upload are same?
You can use Formidable. As It support multipart data. And for retrieve video you can use fs(file system)
Actually you don't save media(image or video) in DB, you store it in some storage drive(locally or cloud) like s3 bucket, and then store its location url in your DB.
and this code might be helpful.
saveImage(urlPath, folderPath, multiple) {
return new Promise((resolve, reject) => {
var timestamp = Date.now();
var filepath = urlPath;
var imageUrl;
var ext = path.extname(filepath || '').split('.');
var extension = ext[ext.length - 1];
var tmp_path = filepath;
imageUrl = folderPath + timestamp + '.' + extension;
if (multiple != '' && multiple != undefined) { imageUrl = folderPath + timestamp + multiple + '.' + extension; }
var target_path = __dirname + '/../' + imageUrl;//Change according to your location.
console.log("target_path", target_path);
mv(tmp_path, target_path, { mkdirp: true }, function (err) { })
return resolve({ status: 1, url: imageUrl });
})
}
Now, urlPath is your media path, foldarPath is path where you want to store your media and multiple is to give unique name.
you can call this method like this.
var multiple = Number(0) + Number(10);
console.log("multiple", multiple);
var saveImage = await 'YOUR_FILE_NAME'.saveImage(files.photo[0].path, 'public/Image/', multiple);
console.log(saveImage);
<video src="video/<%= file.filename %>" controls alt="">
//Try adding the controls command in the video tag. It helps the video run.

Index page in node app only routing to first show page

I'm building a goals app with node/express/psql. When I click on a goal on the index page, I want it to link to the show page for that goal. However, each one is linking to the goal with the id=1. I'm confused because the .forEach I use to print the objects in the first place is working, just not the link. Any help would be appreciated!
index.ejs:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="styles.css">
<meta charset="UTF-8">
<title>Goals</title>
</head>
<body>
<h1>Here's a look at all of your goals!!</h1>
New Goal?
<% goals.forEach(goal => { %>
<div class="goal-container">
<h2><%= goal.description %></h2>
<p><%= goal.step1 %></p>
<p><%= goal.step2 %></p>
<p><%= goal.step3 %></p>
<p><%= goal.step4 %></p>
</div>
<% }) %>
</body>
</html>
controller:
const Goal = require('../models/goal');
const goalsController = {};
goalsController.index = (req, res) => {
Goal.findAll(req.user.id)
.then(goal => {
res.render('goals/', { goals: goal });
})
.catch(err => {
res.status(400).json(err);
});
};
goalsController.show = (req, res) => {
Goal.findById(req.params.id)
.then(goals => {
console.log('goals show');
res.render(`goals/show`, { goals:goals })
})
.catch(err => {
res.status(400).json(err);
});
};
module.exports = goalsController;
routes:
const express = require('express');
const goalsController = require('../controllers/goals-controllers');
const goalsRouter = express.Router();
goalsRouter.get('/', goalsController.index);
goalsRouter.get('/new', goalsController.new);
goalsRouter.get('/:id', goalsController.show);
goalsRouter.get('/:id/edit', goalsController.edit);
goalsRouter.put('/:id', goalsController.update);
goalsRouter.post('/', goalsController.create);
goalsRouter.delete('/:id', goalsController.delete);
module.exports = goalsRouter;
model:
const db = require('../db/config');
const Goal = {};
Goal.findAll = id => {
return db.query(`SELECT * FROM goals JOIN users ON goals.user_id = users.id WHERE goals.user_id = $1`, id)
};
Goal.findById = id => {
console.log('findbyId')
return db.oneOrNone(`SELECT * FROM goals WHERE id = $1`, [id])
};
module.exports = Goal;
Thanks in advance!
I believe there is something wrong with your index.ejs
Try replacing <h2><%= goal.description %></h2>
with <h2><%= goal.description %></h2>

Resources