Reference error when using ejs with express - node.js

I am making a simple weather application using express and passing the weather info I get from my API to the html file, where I am using ejs to display them.
Here is the file for creating the server:
const express = require("express");
const bodyParser = require("body-parser");
const request = require("request");
const app = express();
const apiKey = "*******************";
app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: true }));
app.set("view engine", "ejs");
app.get("/", function (req, res) {
res.render("index", { weather: null, error: null });
});
app.post("/", function (req, res) {
res.render("index");
console.log(req.body.city);
let city = req.body.city;
let url = `http://api.openweathermap.org/data/2.5/weather?q=${city}&units=imperial&appid=${apiKey}`;
request(url, function (err, response, body) {
if (err) {
res.render('index', { weather: null, error: 'Error, please try again' });
} else {
let weather = JSON.parse(body);
if (weather.main == undefined) {
res.render('index', { weather: null, error: 'Error, please try again' });
} else {
let weatherText = `It's ${weather.main.temp} degrees in ${weather.name}!`;
res.render('index', { weather: weatherText, error: null });
}
}
});
});
app.listen(8080, function () {
console.log("Example app listening on port 8080 !");
});
and here is my html file with ejs :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Test</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" media="screen" href="/css/style.css" />
</head>
<body>
<h1>Know Your Weather ! </h1>
<div class="container">
<fieldset>
<form action="/" method="POST">
<input name="city" type="text" class="ghost-input" placeholder="Enter a City" required>
<input type="submit" class="ghost-button" value="Get Weather">
</form>
<% if(weather !== null){ %> <p><%= weather %></p><% } %>
<% if(error !== null){ %> <p><%= error %></p><% } %>
</fieldset>
</div>
</body>
</html>
But when I give an input in the website, I get the following error:
> ReferenceError: /home/anirudh/Desktop/weather-app/views/index.ejs:20
> 18| <input type="submit" class="ghost-button" value="Get Weather">
> 19| </form>
> >> 20| <% if(weather !== null){ %> <p><%= weather %></p><% } %>
> 21| <% if(error !== null){ %> <p><%= error %></p><% } %>
> 22| </fieldset>
> 23| </div>
>
> weather is not defined
> at eval (eval at compile (/home/anirudh/Desktop/weather-app/node_modules/ejs/lib/ejs.js:618:12),
> <anonymous>:11:8)
> at returnedFn (/home/anirudh/Desktop/weather-app/node_modules/ejs/lib/ejs.js:653:17)
> at tryHandleCache (/home/anirudh/Desktop/weather-app/node_modules/ejs/lib/ejs.js:251:36)
> at View.exports.renderFile [as engine] (/home/anirudh/Desktop/weather-app/node_modules/ejs/lib/ejs.js:482:10)
> at View.render (/home/anirudh/Desktop/weather-app/node_modules/express/lib/view.js:135:8)
> at tryRender (/home/anirudh/Desktop/weather-app/node_modules/express/lib/application.js:640:10)
> at Function.render (/home/anirudh/Desktop/weather-app/node_modules/express/lib/application.js:592:3)
> at ServerResponse.render (/home/anirudh/Desktop/weather-app/node_modules/express/lib/response.js:1008:7)
> at /home/anirudh/Desktop/weather-app/server.js:17:9
> at Layer.handle [as handle_request] (/home/anirudh/Desktop/weather-app/node_modules/express/lib/router/layer.js:95:5)
What am I doing wrong with the ejs?

The problem is in the post route you define:
app.post("/", function (req, res) {
res.render("index");
// ...
This call to res.render does not provide any locals, and hence, weather is not defined. I haven't tried it, but this immediately caught my eye, and I am pretty sure that this is the source of the error you encounter – especially since you said that it only happens when you submit data.
I assume that this is an unintended leftover of a previous version or some debugging, since you correctly render a few lines below. If you simply remove this call to res.render, I guess that things should work as expected.

Related

Why is Multer req.file is undefined with this simple file upload?

Let me start off with :I've read through many similar topics, yet can't find the solution.
I just started a fresh react app, and copied the form from the express/multer documentation
<form action="http://localhost:5001/app-dev/us-central1/api/upload" encType="multipart/form-data" method="post">
<div className="form-group">
<input type="file" className="form-control-file" name="uploaded_file"></input>
<input type="text" className="form-control" placeholder="Number of speakers" name="nspeakers"></input>
<input type="submit" value="Get me the stats!" className="btn btn-default"></input>
</div>
</form>
And I have a firebase function running locally with an express app.
const upload = multer({dest: './'})
app.post('/upload', upload.single('uploaded_file'), function (req: any, res: any) {
console.log(req.file, req.body)
});
the request in the network call has these headers
req.file is undefined when logging.
Does anyone see the missing piece?
Thanks a lot
ps. I use the cors middleware to resolve CORS issues (& GET calls are working)
It should work. Here is a minimal working example:
app.js:
const express = require('express');
const multer = require('multer');
const app = express();
const upload = multer({ dest: './' });
app.post('/app-dev/us-central1/api/upload', upload.single('uploaded_file'), function (req, res) {
console.log(req.file, req.body);
res.sendStatus(200);
});
app.listen(5001, () => console.log('Server started at http://localhost:5001'));
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://unpkg.com/react#17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#17/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone#6/babel.min.js"></script>
</head>
<body>
<div id="container">
</div>
<script type="text/babel">
(function () {
const e = React.createElement;
class Upload extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<form action="http://localhost:5001/app-dev/us-central1/api/upload" encType="multipart/form-data" method="post">
<div className="form-group">
<input type="file" className="form-control-file" name="uploaded_file"></input>
<input type="text" className="form-control" placeholder="Number of speakers" name="nspeakers"></input>
<input type="submit" value="Get me the stats!" className="btn btn-default"></input>
</div>
</form>
)
}
}
const domContainer = document.querySelector('#container');
ReactDOM.render(e(Upload), domContainer);
})()
</script>
</body>
</html>
Server logs:
Server started at http://localhost:5001
{ fieldname: 'uploaded_file',
originalname:
'Stack Exchange personalized prediction data 2020-12-21.json',
encoding: '7bit',
mimetype: 'application/json',
destination: './',
filename: 'af7fc0ae20d3404ada7273792db07dc9',
path: 'af7fc0ae20d3404ada7273792db07dc9',
size: 99765 } [Object: null prototype] { nspeakers: '23' }
Client logs:
npx http-server -p 3001 -c-1Starting up http-server, serving ./
Available on:
http://127.0.0.1:3001
http://192.168.31.128:3001
Hit CTRL-C to stop the server
source code: https://github.com/mrdulin/expressjs-research/tree/master/src/stackoverflow/65308716

Uncaught ReferenceError: io is not defined at index 40

var express= require("express")
var bodyParser=require("body-parser")
var app= express()
var http=require('http').Server(app)
var io=require('socket.io')(http)
app.use(express.static(__dirname))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended:false}))
var messages=[
{name:"rohit",message:"hello"},
{name:"rohan",message:"hi"},
]
app.get('/messages', (req,res) =>{
res.send(messages)
})
app.post('/messages',(req,res)=>{
messages.push(req.body)
io.emit('message',req.body)
res.sendStatus(200)
})
io.on('connection',(socket)=>{
console.log('user connected')
})
var server= app.listen(3010, () => {
console.log("Server is listening on port ",server.address().port)
})
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.5.1.min.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
<script>src="http://localhost:3010/socket.io/socket.io.js"</script>
</head>
<body>
<div class="container">
<br>
<div class="jumbotron">
<h1 class="display-4">Send Message</h1>
<br>
<input id ="name" class="form-control" placeholder="Name">
<br>
<textarea id ="message" class="form-control" placeholder="Message"></textarea>
<br>
<button id="send" class="btn btn-success">Send</button>
</div>
<div id="messages">
</div>
</div>
<script>
var socket=io() <!--io is not defined pls help to resove this issue thnks in advance-->
$(()=> {
$("#send").click(() =>{
var message={name: $("#name").val(),message: $("#message").val()}
postMessage(message)
})
getMessages()
})
socket.on('message',addMessages)
function addMessage(message){
$("#messages").append(`<h4> ${message.name} </h4> <p> ${message.message} </p>`)
}
function getMessages(){
$.get("http://localhost:3010/messages",(data)=>{
data.forEach(addMessage);
})
}
function postMessage(message){
$.post("http://localhost:3010/messages",message)
}
</script>
</body>
</html>
This is the code for server.js and index.html respectively. My error:
io is not defined at index 40
I am new to node.js and try making a simple chat app. I know this is an error talked about a lot in here. But after a few posts found via google, it still didn't solve my problem.
use the CDN script
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>

Angular.js (net::ERR_ABORTED 404 (Not Found))

MY server configuration file
const express=require('express');
const app = express();
const logger=require('./utils/logger');
const bodyParser=require('body-parser');
app.use(express.static('public'));
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
app.set("view engine","ejs");
app.use('/', require('./Routes/sellerRoutes'));
app.listen(process.env.PORT||1234, (err)=>{
if(err) {
console.log('An Error has occured', err);
logger.error('Server Not Start ',err);
}
else {
console.log("Server Started");
logger.debug('Server Started');
}
})
My Routing file
const seller=require('express').Router();
const logger=require('../utils/logger');
const adminUser=require('../Models/Userclass');
const password=require('../Models/Passchange');
const operations=require('../db/Helpers/sellerOperations');
seller.post('/change',(req,res)=>{
console.log('kkkkkkkkkkkkkk');
res.render('change');
var newPass=req.body.newPass;
console.log("New Password:::",newPass);
var confirmPass=req.body.confirmPass;
console.log('Confirm Password:::',confirmPass);
var passPanel=new password(newPass,confirmPass);
var pr=operations.findOneAndUpdate(passPanel);
pr.then(data=>{
console.log(data);
res.render('change',{newPass:data.newPass, confirmPass:data.confirmPass});
})
})
seller.post('/submit',(req,res)=>{
res.render('submit');
});
module.exports=seller;
MY ejs (Template Engine) file
<body class="section">
<h1><center>Password Change</center></h1>
<form method="POST" action="submit">
<% var newPass;%> <% var confirmPass; %>
<label for="">New Password:</label>
<input type="password" id="newPass" name="newPass" value="<%=newPass%>">
<div class="cnfrm">
<label for="">Confirm Password:</label>
<input type="password" id="confirmPass" name="confirmPass" value="<%=confirmPass%>">
</div>
<button id="chngepswd" class="btn btn-success">OK</button></a>
</form>
<br>
</body>
My Controller.js file
const app=angular.module('app', []);
app.controller('adminctrl', ($scope,$http,$q)=>{
var newPass=$scope.newPass;
var confirmPass=$scope.confirmPass;
$scope.dochange()=function(){
$http.post('http://localhost:1234/user').then((data)=>{
let defered = $q.defer();
console.log(data);
defered.resolve(data);
}),then((err)=>{
console.log(err);
defered.reject(err);
})
return defered.promise;
}
})
Index.html File
<!DOCTYPE html>
<html lang="en" ng-app='app'>
<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://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<title>Document</title>
<script src="../bower_components/angular/angular.min.js"></script>
<script src="../app.js"></script>
<script src="../js/controller.js""></script>
</head>
<style>
</style>
<body >
<div ng-controller="adminctrl">
<div>
<label for="">New Password</label>
<input type="text" name="newPass" id="newPass" ng-model="newPass">{{newPass}}<br>
<label for="">Confirm Password</label>
<input type="text" name="confirmPass" id="confirmPass" ng-model="confirmPass">{{confirmPass}}<br>
<button ng-click="dochange()">OK</button><br>
</div>
</div>
<br>
</body>
</html>
I am making the front end for my web application. I made index.html file in public folder and I have made an js folder in which I have an controller.js file. I have declared the source of .js file in script tag in HTML file.
But when I load the server it says controller is not found and I have installed bower package manager from which I have installed angular.js. My browser is not able to find neither the bower component in which there is my (angilar.min.js file) nor controller.js file.
It says
net::ERR_ABORTED 404 (Not Found) for every file and even for bower.

Nothing to geocode - Weather API - Nodejs

I am new to Nodejs and trying to use weather api.
When I test the link in browser, it gives me accurate answer
http://api.openweathermap.org/data/2.5/weather?q=karachi&appid=dcf486a78f2b8e898c4b1a464a1b31e1
while it keeps throwing error.
const express = require("express")
var logger = require("morgan")
var path = require("path")
var bodyParser = require("body-parser")
let requested = require('request');
var app=express()
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.set("views", path.resolve(__dirname,"views"))
app.set("view engine",'ejs')
app.use(logger("short"))
app.get("/",function(request,response)
{
response.render("homepage")
})
app.post('/', function(request, response) {
var urlOpenWeatherCurrent = 'http://api.openweathermap.org/data/2.5/weather?'
var queryObject = {
APPID: "dcf486a78f2b8e898c4b1a464a1b31e1",
city: request.body.cityName
}
console.log(queryObject)
requested({
url:urlOpenWeatherCurrent,
q: queryObject // In many tutorials they used 'qs' instead of 'q'. I don't know why.
}, function (err, response, body) {
// response.send('You sent the name ' + request.body.cityName + ".");
if(err){
console.log('error:', error);
} else {
console.log('body:', JSON.parse(body));
}
});
});
app.use(function(request,response)
{
response.status(404)
response.send("Error")
})
app.listen(3000,()=>console.log("Working"))
Error
{ APPID: 'dcf486a78f2b8e898c4b1a464a1b31e1', city: 'karachi' }
'Invalid API key. Please see http://openweathermap.org/faq#error401 for more info.'
If I change q to qs in nodejs, then
{ APPID: 'dcf486a78f2b8e898c4b1a464a1b31e1', city: 'karachi' }
body: { cod: '400', message: 'Nothing to geocode' }
Note that changing q to qs in raw html API link also gives
{"cod":"400","message":"Nothing to geocode"}
I believe from the response that I should use qs in nodejs, because at least this time it is not considering API key wrong. But in the API link, we have q and not qs. So how come qs makes sense? Besides, as far as I Understood, it is not properly concatenating the API strings together, resulting in the malfunctioning. But I don't know how to print the entire link in console to validate what I just said.
views/homepage.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">
<title>Document</title>
</head>
<body>
<form class="pure-form" action="/" method="POST">
<input type="name" placeholder="City name" name="cityName" autofocus required>
<input type="submit" valuue="Go">
</form>
</body>
</html>
embed the "q" and "api key" with open weather url like "http://api.openweathermap.org/data/2.5/weather?q=${city}&units=imperial&appid=${apiKey}"
also Check this link
https://codeburst.io/build-a-weather-website-in-30-minutes-with-node-js-express-openweather-a317f904897b

req.body returns undefinded after setting bodyParser urlencoded to extended as false

I am a newbee to nodejs . I have tried to create simple chat App. The req.body in my app.post seems to return undefinded even after setting my body-parser urlencoded ({extented:false}).can anybody walk me through this?!..thanks in advance
here is my code server.js for server side:
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
app.use(bodyParser.urlencoded({extended: false}))
app.use(bodyParser.json())
app.use(express.static(__dirname))
var messages = [
{name:'Brue',message:'Hello Diana'},
{name:'Diana', message:'Hey Bruce.'} ]
app.get('/messages', (req,res) => {
res.send(messages) })
app.post('/messages', (req,res) => {
messages.push(req.body)
res.sendStatus(200)})
var server = app.listen(8080, (err,data) => {
console.log('The server runs on the port:', server.address().port) })
here is my client side code:
<!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">
<title>Message App</title>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
</head>
<body>
<div class="container">
<br>
<div class="jumbotron">
<h1 class="display-4"> Send Message </h1>
<br>
<input class="form-control" type="text" placeholder="Name">
<br>
<textarea placeholder = "Message" class="form-control" id="mesage" cols="30" rows="10"></textarea>
<br>
<button id = "send" class="btn btn-success"> Send</button>
</div>
<div id="messages"></div>
</div>
<script>
$(() => {
$('#send').click(() => {
var message = { name: $("#name").val(), message: $("#message").val()}
postMessage(message)
})
getMessages() })
function addMessages(message){
$("#messages").append(`<h4>${message.name}</h4> <p> ${message.message} </p>`) }
function getMessages(){
$.get('http://localhost:8080/messages',(data) => {
data.forEach(addMessages); }) }
function postMessage(message){
$.post('http://localhost:8080/messages', message)
}
In your html, you misspelled your textarea's id. It is id="mesage" instead of id="message" with two 's'. And you never set the id of #name. Fix these.
<input class="form-control" id="name" type="text" placeholder="Name">
<textarea placeholder="Message" class="form-control" id="message" cols="30" rows="10"></textarea>
Makes sure that your variable, which u will send is valid. I recommend you to use the chrome debugger in these situations.

Resources