Cannot display data from API request in views - api

I am brand new to Express and Node.js, trying to build server-rendered app which will display some data from API.
This is my code
app.js
var express = require("express");
var app = express();
var request = require("request");
var apiKey = '****************************';
var bodyParser = require("body-parser");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.set('viewEngine', 'ejs');
const options = {
method: 'POST',
url: 'http://api.somethingsomething.com/content/search/v1?',
headers: {
'X-Api-Key': `${apiKey}`,
'Content-Type': 'application/json'
},
body: {
'queryString': 'pigs',
'resultContext' : {
'aspects' :['title','lifecycle','location','summary','editorial' ]
}
},
json: true
}
app.get('/', function(req, res) {
request(options, function(error, response, body) {
if (!error && response.statusCode == 200) {
var info = JSON.stringify(body);
console.log(info);
res.render('index', { results: info}); // this does not render anything
}
})
});
app.listen(3000, function() {
console.log("Listening on port 3000");
})
index.ejs
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="searchResults">
<%= results %>
</div>
</body>
</html>
It does not render index.ejs and cannot display data.
Error: No default engine was specified and no extension was provided.
I tried googling it, but no luck. Any help will be appreciated; Thank you

problem was simple app.set('viewEngine', 'ejs'); was wrong, should be pp.set('view engine', 'ejs');

Related

Passport Express (NodeJS) authentication gives an error

I'm having this problem that Passport Express (NodeJS Framework) gives back an error when testing with Postman. The code looks like this:
passport.use(new BasicStrategy(function verify(username, password, cb) {
cb("Bla", password === "Route")
}));
const app = express()
app.get('/haha', passport.authenticate('basic', { session: false }), (req, res) => {
res.send("Hello World")
console.log("Hello World")
})
const server = app.listen(8080, () => {
console.log("Server started")
})
This is the error from Postman. I did give it as input the above credential
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
Any help would be appreciated. Thank you!

Express update/delete routes are not working but no errors either

I'm learning node express by making a to-do list. I'm having trouble with marking a to-do as complete/incomplete and deleting them. It's not giving me any errors so I'm trying to console log wherever I can.
The _id in the database is console logging so I think I have my variables correct? Please see below the server.js and main.js files for the comments where I think could be wrong.
I've been stuck on this problem for 3 days now...
EDIT: I just noticed findOneAndUpdate() is a mongoose function. I don't have mongoose yet... I think I'm on the right track...
server.js
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
const MongoClient = require("mongodb").MongoClient;
const cors = require("cors");
const { request } = require("mongodb");
const PORT = process.env.PORT || 8000;
app.use(cors());
const username = "hidden";
const password = "hidden";
const connectionString = `mongodb+srv://${username}:${password}#cluster0.7k2ww.mongodb.net/myFirstDatabase?retryWrites=true&w=majority`;
MongoClient.connect(connectionString, { useUnifiedTopology: true }).then(
(client) => {
console.log("Connected to database");
const db = client.db("to-do-list");
const toDoCollection = db.collection("to-dos");
app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(express.static("public"));
app.get("/", async (req, res) => {
const result = await toDoCollection.find().toArray();
const itemsLeft = await toDoCollection.countDocuments({
done: false,
});
res.render("index.ejs", { todos: result, left: itemsLeft });
});
app.post("/addtodo", (req, res) => {
toDoCollection
.insertOne({ todo: req.body.todo, done: false })
.then((result) => {
res.redirect("/");
})
.catch((error) => console.error(error));
});
app.put("/markComplete", async (req, res) => {
try {
await toDoCollection.findOneAndUpdate(
{
_id: req.body.todoId, // Is this line talking with my main.js file?
},
{
$set: { done: true },
},
{ sort: { _id: -1 }, upsert: false }
);
console.log(req.body.todoId);
res.json("Task completed");
} catch (err) {
console.log(err);
}
});
app.put("/markIncomplete", async (req, res) => {
try {
await toDoCollection.findOneAndUpdate(
{
_id: req.body.todoId,
},
{
$set: { done: false },
},
{ sort: { _id: -1 }, upsert: false }
);
console.log(req.body.todoId);
res.json("Task completed");
} catch (err) {
console.log(err);
}
});
app.delete("/deleteToDo", async (req, res) => {
console.log(req.body.todoId);
try {
await toDoCollection
.findOneAndDelete({ _id: req.body.todoId })
.then((result) => {
console.log("todo deleted");
res.json("todo deleted");
});
} catch {
console.log(err);
}
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
}
);
main.js
const deleteTask = document.querySelectorAll(".delete-todo");
const completeTask = document.querySelectorAll(".incomplete");
const incompleteTask = document.querySelectorAll(".complete");
Array.from(deleteTask).forEach((e) => {
e.addEventListener("click", deleteToDoFunc);
});
Array.from(completeTask).forEach((e) => {
e.addEventListener("click", completeToDoFunc);
});
Array.from(incompleteTask).forEach((e) => {
e.addEventListener("click", incompleteToDoFunc);
});
async function deleteToDoFunc() {
console.log("Delete working!");
const todoId = this.parentNode.dataset.id;
console.log(todoId);
try {
const res = await fetch("deleteToDo", {
method: "delete",
headers: { "Content-type": "application/json" },
body: JSON.stringify({
todoId: todoId,
}),
});
const data = await res.json();
console.log(data);
location.reload();
} catch (err) {
console.log(err);
}
}
async function completeToDoFunc() {
console.log("Update working!");
const todoId = this.parentNode.dataset.id;
console.log(todoId);
try {
const res = await fetch("markComplete", {
method: "put",
headers: { "Content-type": "application/json" },
body: JSON.stringify({
todoId: todoId, // Is this line talking with the server.js file?
}),
});
const data = await res.json();
console.log(data);
// location.reload();
} catch (err) {
console.log(err);
}
}
async function incompleteToDoFunc() {
console.log("Incomplete task");
const todoId = this.parentNode.dataset.id;
console.log(todoId);
try {
const res = await fetch("markIncomplete", {
method: "put",
headers: { "Content-type": "application/json" },
body: JSON.stringify({
todoId: todoId,
}),
});
const data = await res.json();
console.log(data);
location.reload();
} catch (err) {
console.log(err);
}
}
index.ejs
<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" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
rel="stylesheet"
href="../css/font-awesome-4.7.0/css/font-awesome.min.css"
/>
<link rel="stylesheet" href="css/style.css" />
<link
href="https://fonts.googleapis.com/css2?family=Montserrat:wght#300;400&display=swap"
rel="stylesheet"
/>
<title>To Do</title>
</head>
<body>
<div class="container">
<header class="flexContainer">
<h1 class="title main-font center">To Do List</h1>
</header>
<form class="center" action="/addtodo" method="POST">
<input type="text" placeholder="Add a To Do" name="todo" />
<button type="submit" class="submitButton">
<i class="fa fa-plus-square"></i>
</button>
</form>
<div class="to-do-list flexContainer">
<ul class="task-list center">
<% todos.forEach(todo => { %>
<li class="todo-name main-font complete-task" data-id="<%=todo._id%>"> <!-- The route should know which to-do to update/delete based on _id -->
<% if (todo.done === true) { %>
<span class="complete"><%= todo.todo %></span>
<% } else { %>
<span class="incomplete"><%= todo.todo %></span>
<% } %>
<span class="fa fa-trash delete-todo"></span>
</li>
<%}) %>
</ul>
</div>
<h2 class="main-font center">Left to do: <%= left %></h2>
</div>
<script type="text/javascript" src="/js/main.js"></script>
</body>
</html>
When you try to update your To-Do List, does it override everything in your document? I see that your using a PUT request instead of a PATCH request, and a PUT request would replace your all your data instead of updating a single field

Failed to load resource: the server responded with a status of 404 (Not Found) on routing

I am trying to route in my project. I want that on clicking connect button the rooms page should get rendered. Home page is working fine but as soon I as click connect it shows Cannot GET /rooms/0b2636b5-c254-47f4-ade8-9e6b745a96d1.The code works fine when instead of routing to rooms it is on root url.
I am new to web development and I tried reading other questions on similar problem but couldn't understand.
Server side(Server.js):
const express = require('express');
const app = express();
const server = require('http').Server(app);
const { v4: uuidV4 } = require('uuid');
const io = require('socket.io')(server);
const { ExpressPeerServer } = require('peer');
const peerServer = ExpressPeerServer(server, {
debug: true
});
app.use('/peerjs', peerServer);
app.set('view engine', 'ejs');
app.use(express.static('public'));
app.get('/', (req, res) => {
res.render('home');
})
app.get('/rooms', (req, res) => {
res.redirect(`/rooms/${uuidV4()}`);
})
app.get('/rooms:room', (req, res) => {
res.render('room', { roomId: req.params.room })
})
server.listen(3000);
Client Side(script.js)
const socket = io('/rooms');
const videoGrid = document.getElementById('video-grid');
var peer = new Peer(undefined, {
path: '/peerjs',
host: '/rooms',
port: '3000'
})
Navigation bar on home.ejs
<nav class="nav">
<li class="nav-link">
Connect
</nav>
room.ejs
<script>
const ROOM_ID = "<%=roomId%>"
</script>
<script src="/socket.io/socket.io.js" defer ></script>
<script src="script.js" defer></script>
Structure of file
public
-script.js
views
-home.ejs
-room.ejs
server.js
You're really close to it, just 1 mistake in this block:
app.get('/rooms:room', (req, res) => {
res.render('room', { roomId: req.params.room })
})
It should be:
app.get('/rooms/:room', (req, res) => {
res.render('room', { roomId: req.params.room })
})
Express documentation page here in case you need it (section Route parameters).

can't connect to other person's video and audio

Hello i am new to peerjs. currently i am trying to code a video call app. i face a problem in it. it shows only my video.it is not showing video and audio of another user .please help i am stuck.
error on console(front end) is
websocket.js:87 WebSocket connection to 'ws://localhost:3000/socket.io/?EIO=4&transport=websocket&sid=uaFPNhLHfKuVgldiAAAA' failed: Invalid frame header
server.js (backend)
const express = require('express');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const { v4: uuidV4 } = require('uuid');
const { ExpressPeerServer } = require('peer');
const peerServer = ExpressPeerServer(server, {
debug: true,
});
app.set('view engine', 'ejs');
app.use(express.static('public'));
app.use('/peerjs', peerServer);
app.get('/', (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) => {
socket.join(roomId);
socket.to(roomId).emit('user-connected', userId);
});
});
server.listen(3000, () => {
console.log('running...');
});
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" />
<script>
const ROOM_ID = '<%= roomId %>';
</script>
<script src="https://unpkg.com/peerjs#1.3.1/dist/peerjs.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<title>Document</title>
<link rel="stylesheet" href="style.css" />
<style>
#video-grid {
display: grid;
grid-template-columns: repeat(auto-fill, 250px);
grid-template-rows: 160px;
}
video {
height: 100%;
width: 100%;
object-fit: cover;
}
</style>
</head>
<body>
<div id="video-grid"></div>
<script src="script.js"></script>
</body>
</html>
script.js
const socket = io('/');
const videoGrid = document.getElementById('video-grid');
const myPeer = new Peer(undefined, {
host: '/',
port: '3000',
path: '/peerjs',
});
const myVideo = document.createElement('video');
myVideo.muted = true;
navigator.mediaDevices
.getUserMedia({
video: true,
audio: true,
})
.then((stream) => {
addVideoStream(myVideo, stream);
myPeer.on('call', (call) => {
call.answer(stream);
const video = document.createElement('video');
call.on('stream', (userVideoStream) => {
addVideoStream(video, userVideoStream);
});
});
socket.on('user-connected', (userId) => {
connectToNewUser(userId, stream);
});
});
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);
}

Express file upload using multer file is undefined always

I have tried to make an api to upload files in express using multer middleware but the request.file is undefined.
the express code is given below,
const express = require("express");
var multer = require('multer');
const cors = require("cors");
var app = express();
app.use(cors({ origin: true }));
const multerMid = multer({
storage: multer.memoryStorage(),
limits: {
fileSize: 5 * 1024 * 1024,
},
});
app.post('/saveFile', multerMid.single('dp'), (request,response)=>{
try{
var dp = request.file;
if(dp)
{
return response.send("file uploaded");
}
else{
return response.send("No file uploaded");
}
}catch(error)
{
return response.send(error.errorMessage);
}
});
exports.app = functions.https.onRequest(app);
No file uploaded
this is what I always receive when I post a file to the route using the following html.
<html>
<head>
</head>
<body>
<form action = "<server>/saveFile" method="post" enctype="multipart/form-data">
<input type="file" name="dp"/>
<input type="submit" value="Save">
</form>
</body>
</html>
I need to upload the file to file to firebase storage thats why I don't use a static storage location in the multer object,
I am stuck please help.
Here a middleware needs to be defined
app.post('/saveFile', multerMiddleWare, (request,response)=>{...});
const multerMiddleWare = (req, res, next) => {
multerMid(req, res,
(error) => {
if (!error) return next();
return next('error');
});
};
const multerMid = multer({
storage: multer.memoryStorage(),
limits: {
fileSize: 5 * 1024 * 1024,
},
}).single('dp');