Page won't redirect when uploading to db with multer - redirect

I'm trying to upload (update acutally) an image to a db and then redirect to profile page, i tried everything and the photo is updated successfully in the db but page wont redirect.
If i dont attach an image everything is ok and user gets redirected.
If i do attach an image user just stays on form page, no errors pop up, page just gets refreshed (photo gets updated in db successfully)
post route
var store = require("./multer");
router.post("/:username/edit", isUser, personalContent, store.single("profilePic"), async (req, res) => {
try {
if (req.file) {
await User.updateOne(
{ username: req.user.username },
{
username: req.params.username,
dateOfBirth: req.body.date,
filename: req.file.originalname,
contentType: req.file.mimetype,
imageBase64: fs.readFileSync(req.file.path).toString("base64"),
},
{ upsert: true }
);
} else {
await User.updateOne(
{ username: req.user.username },
{
username: req.params.username,
dateOfBirth: req.body.date,
},
{ upsert: true }
);
}
res.redirect("/profile/" + req.params.username + "?msg=Profile updated successfully");
} catch (err) {
console.log(err);
res.redirect("/profile/" + req.params.username + "?msg=Error while updating profile");
}
});
ejs form
<form action="/profile/<%= user.username %>/edit" enctype="multipart/form-data" method="POST">
<% if(error){ %> <%= error %> <% } %> <% if(msg){ %> <%= msg %> <% } %>
<div>
<label for="username">Username: </label>
<input type="text" name="username" value="<%= user.username %>" disabled />
</div>
<div>
<label for="date">Date of birth: </label>
<input type="date" name="date" required value="<%= user.dateOfBirth.toISOString().split("T")[0] %>" />
</div>
<div>
<label for="profpic">Profile picture:</label>
<input type="file" name="profilePic" />
<div>
<% if(user.imageBase64){ %>
<img src="data:<%=user.contentType%>;base64,<%=user.imageBase64%>" alt="" style="height: 3rem" />
<% }else{ %> Add profile picture <% } %>
</div>
</div>
<button type="submit">Submit</button>
</form>
multer.js
const multer = require("multer");
//set storage
var storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "uploads");
},
filename: (req, file, cb) => {
cb(null, file.fieldname + "-" + Date.now());
},
});
module.exports = store = multer({ storage: storage });

The issue was with LiveServer chrome extension, it was messing something up with redirects. Now this question seems stupid to me but if someone stumbled upon this I hope I could help

Related

usersWithSecrets is not defined in forEach called in ejs

Am getting this error when google auth redirects to my secrets page. And also in the secrets page I can't post secrets as they aren't posted in my database. I don't know which elements I have called wrongly.
<%- include('partials/header') %>
<div class="jumbotron text-center">
<div class="container">
<i class="fas fa-key fa-6x"></i>
<h1 class="display-3">You've Discovered My Secret!</h1>
<% usersWithSecrets.forEach(function(foundUsers){ %>
<p class="secret-text"><%=foundUsers.secret%></p>
<% }) %>
<hr>
<a class="btn btn-light btn-lg" href="/logout" role="button">Log Out</a>
<a class="btn btn-dark btn-lg" href="/submit" role="button">Submit a Secret</a>
</div>
</div>
<%- include('partials/footer') %>
app.get("/secrets", function(req,res){
if (req.isAuthenticated()) {
User.find({"secret": {$ne: null}}, function(err, foundUsers){
if(foundUsers){
res.render("secrets", {usersWithSecrets: foundUsers});
}else {
console.log(err);
}
});
app.post("/submit", function(req, res){
const submittedSecret = req.body.secret;
User.findById(req.user.id, function(err, foundUser){
if (err) {
console.log(err);
}else{
if (foundUser) {
foundUser.secret=submittedSecret;
submittedSecret.save(function(){
res.redirect("/secrets");
});
}
}
});
});
The first block of code should catch the user and redirect them to the app.get(secrets)
The second block is a user can post a secret and caught in the database but the page keeps loading infinitely.

Product can not be deleted

I am having the following problem in my project. I am trying to delete an added product but unfortunately, it cannot be deleted. So let me show you my code.
First I have the Product.js model.
static deleteById(prodId){
const db = getDb();
return db
.collection('products')
.deleteOne({_id: new mongodb.ObjectId(prodId) })
.then(result => {
console.log('Deleted');
})
.catch(err => {
console.log(err);
});
}
Then I use deleteById function in my controller Admin.js file.
exports.postDeleteProduct = (req, res, next) => {
const prodId = req.params.productId;
Product.deleteById(prodId)
.then(() => {
console.log('DESTROYED PRODUCT');
res.redirect('/admin/products');
})
.catch(err => console.log(err));
};
After doing that I am creating the necessary route in the routes->admin.js file.
const path = require('path');
const express = require('express');
const adminController = require('../controllers/admin');
const router = express.Router();
// /admin/add-product => GET
router.get('/add-product', adminController.getAddProduct);
// admin/products => GET
router.get('/products', adminController.getProducts);
// /admin/add-product => POST
router.post('/add-product', adminController.postAddProduct);
router.get('/edit-product/:productId', adminController.getEditProduct);
router.post('/edit-product', adminController.postEditProduct);
router.post('/delete-product', adminController.postDeleteProduct);
module.exports = router;
Finally, there is the HTML file which contains the delete button.
<main>
<% if (prods.length > 0) { %>
<div class="grid">
<% for (let product of prods) { %>
<article class="card product-item">
<header class="card__header">
<h1 class="product__title">
<%= product.title %>
</h1>
</header>
<div class="card__image">
<img src="<%= product.imageUrl %>" alt="<%= product.title %>">
</div>
<div class="card__content">
<h2 class="product__price">$
<%= product.price %>
</h2>
<p class="product__description">
<%= product.description %>
</p>
</div>
<div class="card__actions">
Edit
<form action="/admin/delete-product" method="POST">
<input type="hidden" value="<%= product._id %>" name="productId">
<button class="btn" type="submit">Delete</button>
</form>
</div>
</article>
<% } %>
</div>
<% } else { %>
<h1>No Products Found!</h1>
<% } %>
</main>
<%- include('../includes/end.ejs') %>
Here is my repo.
How can the delete problem be fixed?

Handlebars Form no run Mongodb delete function - typeError gfs.deleteOne

The form below sends images/files to Mongodb using the handlelebars (.hbs) engine and multer-gridfs-storage (Mongodb FIles), but by clicking delete it generates the following error:
TypeError: gfs.deleteOne is not a function
Also, it does not load the thumbnail of the attached photo
Ps: I think the error is in HBS form.
Full code :
https://github.com/rebek/upFileHBS
<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>
{{#each files}}
<div class="card card-body mb-3">
{{#if file.isImage}}
<img src="image/{{this.filename}}" alt="">
{{else}}
{{this.filename}}
<form method="POST" action="/files/{{this._id}}?_method=DELETE">
<button class="btn btn-danger btn-block mt-4">Delete</button>
</form>
</div>
{{/if}}
{{/each}}
</div>
</div>
</div>
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 === 'image/jpeg' ||
file.contentType === 'image/png'
) {
file.isImage = true;
} else {
file.isImage = false;
}
});
res.render('index', { files: files });
}
});
});
...
app.delete('/files/:id', (req, res) => {
gfs.deleteOne({ _id: req.params.id, root: 'uploads' }, (err, GridFSBucket) => {
if (err) {
return res.status(404).json({ err: err });
}
res.redirect('/');
});
});
gfs.files.deleteOne({ filename: req.params.filename}, (err) => {
if (err) return res.status(500).json({ success: false })
return res.json({ success: true });
})
using the above will delete the file

Meteor + React: Append response to DOM after a Meteor.call?

I am super new to React and quite new to Meteor.
I am doing a Meteor.call to a function ('getTheThing'). That function is fetching some information and returns the information as a response. In my browser I can see that the method is returning the correct information (a string), but how do I get that response into the DOM?
(As you can see, I have tried to place it in the DOM with the use of ReactDOM.findDOMNode(this.refs.result).html(response);, but then I get this error in my console: Exception in delivering result of invoking 'getTheThing': TypeError: Cannot read property 'result' of undefined)
App = React.createClass({
findTheThing(event) {
event.preventDefault();
var username = ReactDOM.findDOMNode(this.refs.textInput).value.trim();
Meteor.call("getTheThing", username, function(error, response){
console.log(response);
ReactDOM.findDOMNode(this.refs.result).html(response);
});
ReactDOM.findDOMNode(this.refs.textInput).value = "";
},
render(){
return(
<div className="row">
<div className="col-xs-12">
<div className="landing-container">
<form className="username" onSubmit={this.findTheThing} >
<input
type="text"
ref="textInput"
placeholder="what's your username?"
/>
</form>
</div>
<div ref="result">
</div>
</div>
</div>
);
}
});
this is under the different context, thus does not contain the refs there. Also, you cannot set html for the Dom Element. You need to change into Jquery element
var _this = this;
Meteor.call("getTheThing", username, function(error, response){
console.log(response);
$(ReactDOM.findDOMNode(_this.refs.result)).html(response);
});
Though i recommend you to set the response into the state and let the component re-rendered
For a complete React way
App = React.createClass({
getInitialState() {
return { result: "" };
},
shouldComponentUpdate (nextProps: any, nextState: any): boolean {
return (nextState['result'] !== this.state['result']);
},
findTheThing(event) {
event.preventDefault();
var username = ReactDOM.findDOMNode(this.refs.textInput).value.trim();
Meteor.call("getTheThing", username, function(error, response){
console.log(response);
_this.setState({ result: response });
});
ReactDOM.findDOMNode(this.refs.textInput).value = "";
},
render(){
return(
<div className="row">
<div className="col-xs-12">
<div className="landing-container">
<form className="username" onSubmit={this.findTheThing} >
<input
type="text"
ref="textInput"
placeholder="what's your username?"
/>
</form>
</div>
<div ref="result">{this.state['result']}</div>
</div>
</div>
</div>
);
}
});

how send Post request with ajax in ember.js?

I want to send a POST (not GET) request to the server with ember.js. I don't know which function I need at "which function here", but I want to send it to the server for a login request.
App.LoginController = Ember.ObjectController.extend({
actions: {
userLogin: function(user) {
// which function here?
?? ("http://siteurl/api/authentication/login/&username=" + user.username + "&password=" + user.password + "");
this.transitionTo('cat');
},
cancelLogin: function() {
this.transitionTo('menu');
}
}
});
App.UserFormComponent = Ember.Component.extend({
actions: {
submit: function() {
this.sendAction('submit', {
username: this.get('username'),
password: this.get('password')
});
},
cancel: function() {
this.sendAction('cancel');
}
}
});
down here template code
<script type="text/x-handlebars" data-template-name="login">
<header class="bar bar-nav">
<h1 class="title">inloggen</h1>
{{#link-to 'menu' class="icon icon icon-bars pull-right"}}{{/link-to}}
</header>
<!-- SHOW LOADER -->
<div class="content">
<div class="content-padded">
{{user-form submit="userLogin" cancel="cancelLogin" submitTitle="login"}}
</div>
</script>
<script type="text/x-handlebars" data-template-name="components/user-form">
<form {{action "submit" on="submit"}}>
<p><label>gebruikersnaam {{input type="text" value=username}}</label></p>
<p><label>wachtwoord {{input type="password" value=password}}</label></p>
<input type="submit" class="btn btn-primary btn-block" {{bindAttr value=submitTitle}}>
<button class="btn btn-negative btn-block" {{action "cancel"}}>Cancel</button>
</form>
</script>
Ember doesn't have any built in communication layer, you can use jquery for such calls.
App.LoginController = Ember.ObjectController.extend({
actions: {
userLogin: function(user) {
$.ajax({
type: "POST",
url: "http://siteurl/api/authentication/login/&username=" + user.username + "&password=" + user.password,
data: { name: "John", location: "Boston" }
})
this.transitionTo('cat');
},
cancelLogin: function() {
this.transitionTo('menu');
}
}
});