Req.File.Path is undefined - mysql

I am trying to use multer to upload an image to a mysql database , and I am getting an error stating
TypeError: Cannot read property 'path' of undefined
my App.js
var multer = require('multer');
app.use(express.static("public"));
app.post("/updateImage/add",multer({ dest: './public/uploads/'}).single('img') ,contentUpdate.addImage);
my contentUpdate.js
exports.addImage = function(req, res) {
var path = (req.file.path).replace("public/", '');
console.log(path);
var data =
{
image: path
};
var URLs = data.PageURL;
connection.query('INSERT INTO `updatedimages` SET ?', [data], function(err, rows)
{
if (err)
{
console.log(err);
} else
{
req.flash('success','Entry Successful');
return res.redirect(URLs);
}
});
};
my updateImage.handlebars
<form id="myForm" action='/updateImage/add' method='POST' >
<div class="col-md-12" >
<input name='img' type="file" class="form-control" required/>
</div>
<div>
<button type="submit" class="glyphicon glyphicon-submit btn btn-primary ">
</div>

You need to set the proper encoding type in the HTML:
<form id="myForm" action='/updateImage/add' method='POST' enctype='multipart/form-data'>
Even so, it's always good to also validate the input:
if (! req.file || ! req.file.path) {
return res.sendStatus(400);
}

Change the following:
<input name='img' type="file" class="form-control" required/>
to
<input name='file' type="file" class="form-control" required/>
And then try:
app.post("/updateImage/add",multer({ dest: './public/uploads/'}).single('file') ,contentUpdate.addImage);

Related

User Input in HTML Form to use as route parameter in express

I have a HTML form that asks the user for a number:
<div class="get-players">
<form action = "/db/:number" id="getPlayers" method="GET">
<textarea id="num" name="num" rows="3" cols="30"></textarea>
<input class="btn btn-info" type="submit" value="GET" id="submit">
</form>
</div>
I want to use the number that the user inputs as the req.param to find a document in my MongoDB collection:
app.get('/db/:number', async function (req, res) {
await client.connect();
const database = client.db("lab5");
const coll = database.collection("players");
console.log(coll);
var players = coll.find({}).toArray().then(() => {
coll.find({}).toArray(function (err, symbols) {
if (!err) {
var output;
var number = req.params['number'];
console.log(number);
var all = symbols[number].data;
res.send(all);
//console.log("all: ", all);
}
});
});
});
For some reason, it is not reading the number in the form as the parameter. What is the fix for this?

Why is my axios get request is not working (login)

I´m currently working on a login-page for a school-prohect. I´m using vue.js and tried to use axios to run my get-request. My problem is, that I don´t even get into .then() --> alert(TEST1) is the last thing showed.
I don´t get any error
Does anyone know why I have this problem and how to solve it?
Thanks!
CODE:
<template>
....
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-6" id="formsCSS">
<form id="login" method="get">
<div class="form-group">
<input type="text" name="username" id="username" class="form-control" placeholder="Username" required maxlength="50">
</div>
<div class="form-group">
<input type="password" name="password" class="form-control" id="password" placeholder="Password" required>
</div>
<button #click="login" type="submit" name="login_button" class="block">Login</button>
</form>
....
</div>
</template>
<script>
//import axios from './node_modules/axios/index.js';
import axios from 'axios';
export default {
methods: {
login() {
var usrn = document.getElementById("username").value;
var passwd = document.getElementById("password").value;
var usesGranted = 50;
alert("TEST0");
this.doGetRequest(usrn, passwd, usesGranted, false);
},
doGetRequest(passwd, usrn, usesGranted, logedIn) {
alert("TEST1");
axios.get('https://moray.xyz/trawaapi/token/obtainToken.php', {
data: {
auth: {
username: usrn,
password: passwd
},
uses: usesGranted
}
})
.then((response) => {
//Informationen die für Requests benötigt werden in der sessionStorage abspeichern
alert("TEST2");
console.log(response);
sessionStorage.setItem("token", response);
sessionStorage.setItem("password", passwd);
sessionStorage.setItem("username", usrn);
sessionStorage.setItem("uses", usesGranted)
})
.catch((error) => {
//Neuen Token anfordern
if (error == 401) {
if (logedIn == true)
alert("....");
}
console.error(error);
});
}
}
};
</script>
You have to prevent form from being sent. Change remove onclick from button and add another event to the form tag:
<form #submit.prevent="yourFunction" id="login">
As we prevent Email sending and just running yourFunction - we do not need to use method attribute.

I cannot show my output JSON file from server in an HTML page

Here's my server side code snippet (backend):
const express = require('express');
const bodyparser = require('body-parser');
const path = require('path');
const mongoose = require('mongoose');
const { quotemodel } = require('./model/user')
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost:27017/qouteDB', { useNewUrlParser: true, useCreateIndex: true, useUnifiedTopology: true });
let app = express();
app.use(express.static(__dirname + '/public'));
app.use(bodyparser.urlencoded({ extended: false }));
app.use(bodyparser.json());
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, './public/quotes/qoutes.html'))
})
app.post('/post', (req, res) => {
let newQoute = new quotemodel();
newQoute.title = req.body.title;
newQoute.author = req.body.author;
newQoute.body = req.body.body;
newQoute.save(function(err, savedObject) {
if (savedObject) { res.redirect('/viewquotes/' + req.body.author) } else { res.send(err) }
})
})
app.get('/viewquotes/:author', (req, res) => {
console.log('Salam');
quotemodel.findOne({ author: req.params.author }).then((quotemodel) => {
if (!quotemodel) {
res.send().json({
Error: 'Something Went Wornd' + err
})
}
let data = ({
title: quotemodel.title,
author: quotemodel.author,
date: quotemodel.createdAt,
body: quotemodel.body
})
res.send(data)
console.log(data);
})
})
When I run the server and get to localhost:3001/ my HTML page is loading on the port. I can enter my data and I use the (author) item form inserting in url. Next, I use the (author) as param I can access to MongoDB database and I can get my specific data and send it as JSON.
My question
I want the following points:
When redirect to (/viewquotes/:author) my second page(OutPut) open
and when the second page is opened my JSON data rendered into Form
Here is my model:
const mongoose = require('mongoose');
const PersianDate = require('persian-date');
PersianDate.toLocale('en')
let DateAt = new PersianDate().format('YYYY/MMMM/DD')
var qouteschema = mongoose.Schema({
author: String,
body: String,
title: String,
createdAt: { type: String, default: DateAt }
})
let quotemodel = mongoose.model('quotemodel', qouteschema);
module.exports = {
quotemodel
}
this is my HTML Form For Input
<form action="/post" method="POST">
<input id="title" name="title" type="text">
<input id="body" name="body" type="text">
<input id="author" name="author" type="text">
<input id="send" value="send" type="submit">
</form>
This my HTML Form for OutPut
<body>
<div>
<input type="text" name="author" id="author">
<input type="text" name="body" id="body">
<input type="text" name="title" id="title">
<input type="date" name="time" id="time">
<input type="button" onclick="NewIncom()">
</div>
<div class="viewquotes"></div>
</body>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<script src="../viewqoutes.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
function NewIncom() {
axios.get('http://http://localhost:3001/viewquotes')
.then(function(response) {
// handle success
document.getElementById("author").value = response.data.author;
document.getElementById("body").value = response.data.body;
document.getElementById("title").value = response.data.title;
document.getElementById("time").value = response.data.date;
})
}
</script>
Sounds like you need a templating engine for your html pages. Then you could use the data you send with the response to populate fields.
EJS is really easy to use. https://github.com/tj/ejs
Then you could do something like:
<% if (quote) { %>
<form action="/post" method="POST">
<input id="title" name="title" type="text" value="<% quote.title %>">
<input id="body" name="body" type="text" value="<% quote.body %>">
<input id="author" name="author" type="text" value="<% quote.author %>">
<input id="send" value="send" type="submit">
</form>
<% } %>

AngularJS hiding input field

I am writing a login page with register and login options using AngularJS. There are three input fields: username, password and name. I want name field to appear when I click to register button and disappear when I click to login button. Therefore I want to change input field's class to 'hidden' on click and let css handle the job. How can I do it using AngularJS? Is there a better way to hide the name input field?
HTML:
<h2>Welcome to Mail Service</h2>
<form action="/action_page.php">
<div class="imgcontainer">
<img src="images/img_avatar2.png" alt="Avatar" class="avatar">
</div>
<div class="container">
<label><b>Username</b></label><br>
<input type="text" placeholder="Enter Username" name="uname" required ng-model="user.username"><br>
<label><b>Password</b></label><br>
<input type="password" placeholder="Enter Password" name="psw" required ng-model="user.password"><br>
<!-- NAME INPUT FIELD -->
<div class="textField-hidden">
<label><b>Name</b></label><br>
<input type="text" placeholder="Enter Name" ng-model="user.name">
</div><br>
<button type="submit" ng-click="login()">Login</button><br>
<button type="submit" ng-click="register()">Register</button>
</div>
</form>
AngularJS Controller:
app.controller('LoginCtrl', ['$scope', '$resource', '$location',
function($scope, $resource, $location)
{
$scope.login = function()
{
var loginRequest = $resource('/api/login');
loginRequest.save($scope.user, function(response)
{
});
};
$scope.register = function()
{
var registerRequest = $resource('/api/register');
loginRequest.save($scope.user, function(response)
{
});
};
}]);
You need to use ng-hide or ng-show directive (based on your context), and provide it with appropriate condition value like this:
$scope.showName = false;
$scope.login = function() {
// Your code
$scope.showName = false;
}
$scope.register = function() {
// Your code
$scope.showName = false;
}
Change your HTML accordingly:
<input ng-show="showName" type="{{type}}" placeholder="Enter Name" ng-model="user.name">
In this way, the input box will be shown only if the expression of ng-show evaluates to true. Alternatively, ng-if can be used similar to ng-show, but it works a bit different.
just populate a variable as true when you click register and set that variable as false when you click login.
<h2>Welcome to Mail Service</h2>
<form action="/action_page.php">
<div class="imgcontainer">
<img src="images/img_avatar2.png" alt="Avatar" class="avatar">
</div>
<div class="container">
<label><b>Username</b></label><br>
<input type="text" placeholder="Enter Username" name="uname" required ng-model="user.username"><br>
<label><b>Password</b></label><br>
<input type="password" placeholder="Enter Password" name="psw" required ng-model="user.password"><br>
<!-- NAME INPUT FIELD -->
<div class="textField-hidden" ng-show="register">
<label><b>Name</b></label><br>
<input type="text" placeholder="Enter Name" ng-model="user.name">
</div><br>
<button type="submit" ng-click="login()">Login</button><br>
<button type="submit" ng-click="register()">Register</button>
now populate $scope.register as true when you click register
app.controller('LoginCtrl', ['$scope', '$resource', '$location',
function($scope, $resource, $location)
{
$scope.register=false;
$scope.login = function()
{
var loginRequest = $resource('/api/login');
$scope.register=false;
loginRequest.save($scope.user, function(response)
{
});
};
$scope.register = function()
{
var registerRequest = $resource('/api/register');
$scope.register=true;
loginRequest.save($scope.user, function(response)
{
});
};
}]);
You can use a variable for input fields type and hide it
HTML:
<input type="{{type}}" placeholder="Enter Name" ng-model="user.name">
JS:
app.controller('LoginCtrl', ['$scope', '$resource', '$location',
function($scope, $resource, $location)
{
$scope.login = function()
{
$scope.type="hidden";
var loginRequest = $resource('/api/login');
loginRequest.save($scope.user, function(response)
{
});
};
$scope.register = function()
{
$scope.type="text";
var registerRequest = $resource('/api/register');
loginRequest.save($scope.user, function(response)
{
});
};
}]);
An alternative will be to use ng-if or ng-hide/ng-show defined on a $scope variable and trigger a boolean value for this variable according to your needs.

How can i move value from angular form to server nodejs

- This is the html:
<body ng-controller="stripeController">
<form action="/stripe" method="POST" id="payment-form">
<span class="payment-errors"></span>
<div class="from-row">
<lebel>
<span>Price:{{getTotal}}$</span>
<input type="hidden" data-stripe="number">
</lebel>
</div>
<div class="form-row">
<label>
<span>Card Number</span>
<input type="number" size="20" data-stripe="number">
</label>
</div>
<div class="form-row">
<label>
<span>Expiration (MM/YY)</span>
<input type="text" size="2" data-stripe="exp_month">
</label>
<span> / </span>
<input type="text" size="2" data-stripe="exp_year">
</div>
<div class="form-row">
<label>
<span>CVC</span>
<input type="text" size="4" data-stripe="cvc">
</label>
</div>
<input type="submit" class="submit" value="Submit Payment">
</form>
</body>
This is the controller code:
app.controller('stripeController', function($scope, $http) {
$http.get('/api/me').success(function (response) {
$scope.userInfo = response;
$scope.isCartEmpty = true;
$scope.userCart = [];
if($scope.userInfo.cart.length>0){
$scope.isCartEmpty= false;
}
console.log($scope.isCartEmpty);
for(var i=0;i<$scope.userInfo.cart.length;i++){
$scope.userCart[i] = $scope.userInfo.cart[i].productId
}
var y = 0;
$scope.getTotal =0;
for(i=0;i<$scope.userCart.length;i++) {
$http.get('/api/product/' + $scope.userCart[i]).success(function
(response) {
$scope.userInfo.cart[y].name = response.name;
$scope.userInfo.cart[y].price = response.price;
$scope.getTotal+= response.price;
y++;
});
}
});
});
This is the node.js post function :
router.post('/stripe', function(req, res){
//Need to check if the cart empty than re-direct to catalog.
var stripe = require("stripe")(
"sk_test_mypass"
);
stripe.charges.create({
amount: ????? * 100,
currency: "usd",
source: req.body.stripeToken, // obtained with Stripe.js
description: "Test Charge"
}, function(err, charge) {
if(err){
console.log("Error");
}
console.log("Successfully bought product!");
});
});
-I have 1 questions:
In the node.js function where I put "?????" how can I get data from the
html form. When I type req.body.getTotal I don't get the data...
You'll want to send it in a hidden field, but it would be better to calculate the total from the product IDs and quantities in the Cart on the server side so there's no opportunity for the amount to be changed client side.