"Cannot read properties undefined (reading 'id')" error Node.JS - node.js

I want to make a mssql connection with Node.JS and pull the data whose id is given in the table named "test" from my database named "test" in the detail.ejs/{id} page.
App.js:
const sql = require("mssql/msnodesqlv8");
const config = {
user: "AYBAR\\Aybar Ülgen",
password: "",
server: "AYBAR",
database: "nodejs",
driver: 'msnodesqlv8',
options:{
trustedConnection: true
},
};
sql.connect(config, function (err) {
if (err) console.log(err);
console.log("Connected to SQL Server");
});
app.get('/detay/:id', async (req, res) => {
const id = req.params.id;
const query = `SELECT * FROM deneme WHERE id = ${id}`;
sql.query(query, (err, result) => {
if (err) throw err;
const data = result[0];
res.render('detay', { data });
});
});
Detay.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>Document</title>
</head>
<body>
<p>ID: <%= data.id %></p>
<p>Deneme: <%= data.deneme %></p>
<p>Veri bulunamadı.</p>
</body>
</html>
error message:
TypeError: D:\masaüstü\yazilim\nodejs\views\detay.ejs:10
8| </head>
9| <body>
>> 10| <p>ID: <%= data.id %></p>
11| <p>Deneme: <%= data.deneme %></p>
12| <p>Veri bulunamadı.</p>
13|
Cannot read properties of undefined (reading 'id')
at eval ("D:\\masaüstü\\yazilim\\nodejs\\views\\detay.ejs":12:31)
at detay (D:\masaüstü\yazilim\nodejs\node_modules\ejs\lib\ejs.js:703:17)
at tryHandleCache (D:\masaüstü\yazilim\nodejs\node_modules\ejs\lib\ejs.js:274:36)
at exports.renderFile [as engine] (D:\masaüstü\yazilim\nodejs\node_modules\ejs\lib\ejs.js:491:10)
at View.render (D:\masaüstü\yazilim\nodejs\node_modules\express\lib\view.js:135:8)
at tryRender (D:\masaüstü\yazilim\nodejs\node_modules\express\lib\application.js:657:10)
at Function.render (D:\masaüstü\yazilim\nodejs\node_modules\express\lib\application.js:609:3)
at ServerResponse.render (D:\masaüstü\yazilim\nodejs\node_modules\express\lib\response.js:1039:7)
at D:\masaüstü\yazilim\nodejs\deneme.js:49:11
at D:\masaüstü\yazilim\nodejs\node_modules\mssql\lib\base\request.js:448:9
Database:
enter image description here
I said what is the error, I want the solution of the error

Related

delete method is returning 404 error while creating a rest api

I was creating a rest api and the delete request is not being read.
this was the code
app.delete("/students:/id", async (req, res) => {
console.log("in delete")
try {
const _id = req.params.id
const delete_student = await Student.findOneAndDelete(_id)
console.log(req.params.id)
if(!req.params.id){
return res.status(400).send()
}
res.send(delete_student).status(200)
} catch (error) {
res.status(500).send(error)
}
})
and this is the response
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot DELETE /62b93a487624a06ef8756439</pre>
</body>
</html>
The path should be declared as:
app.delete("/students/:id", async (req, res) => { ... })

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>

NodeJS Mongoose insert event to public/index.html

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();

Use a Checkbox to Show Disabled Users

I'm making a website in which I show enabled users in a Bootstrap by default, but there's a checkbox to show all users. But I'm not sure how I can go about implementing it properly.
I thought about doing:
<form class="" action="/admin" method="get">
<input type="checkbox" name="showDisabled" value="">
<input type="submit" name="" value="">
</form>
And in my /admin route:
if (req.body.showDisabled) {
User.find({}, (err, users) => {
if (err) {
console.log(err);
}
}).then((users) => {
res.render('pages/userTable', {users: users});
})
} else if (!req.body.showDisabled) {
User.find({enabled: true}, (err, users) => {
if (err) {
console.log(err);
}
}).then((users) => {
res.render('pages/userTable', {users: users});
})
}
But that seems really janky. What's a better way to do it?
You can try this:
Router
app.get('/getDiasbleUser', function(req, res) {
var getDiasbleUser = req.params.showDisabled
if (getDiasbleUser == "Yes") {
User.find({}, (err, users) => {
if (err) {
console.log(err);
}
}).then((users) => {
res.send(users);
})
} else if (getDiasbleUser == "No") {
User.find({
enabled: true
}, (err, users) => {
if (err) {
console.log(err);
}
}).then((users) => {
res.send(users);
})
}
})
HTML (Template)
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<form class="" action="/admin" method="get">
<input type="checkbox" id="disableId" name="showDisabled" value=""><br>
<div id="appendValue"></div>
<br>
<button class="btn btn-primary">Submit</button>
</form>
</div>
</body>
//Ajax call
<script>
$('#disableId').on('click', function () {
$(this).val(this.checked ? 1 : 0);
//console.log($(this).val());
var url = "";
if($(this).val() == 1){
url = "/getDiasbleUser?showDisabled=yes"
} else {
url = "/getDiasbleUser?showDisabled=no"
}
$.ajax({
url: url,
success: function(data){
//Here data will be return result(You will append into div or table)
//like : $('#appendValue').append(data)
}
})
});
</script>
</html>

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