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

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

Related

Page won't redirect when uploading to db with multer

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

I dont see the issue with the setInterval

In this code, I would like to clear the message after I successfully sent a message via the form I set up a setInterval but it does not work on the specified code but work when I try it in the console. log.
here is the code the component success-message have the message saying that the message has been sent successfully but won't update with the setInterval.
<template>
<success-message v-if="!successMessage" ></success-message>
<!-- <div v-show="successMessage"> -->
<form #submit.prevent="submitForm" >
<div class="form-control">
<label for='name'>Your Name</label>
<input type="name" id="name" v-model.trim="name"/>
</div>
<div class="form-control">
<label for='email'>Your email</label>
<input type="email" id="email" v-model.trim="email"/>
</div>
<div>
<label for='message'>Your message</label>
<textarea row="5" id="message" v-model.trim="message"></textarea>
</div>
<p class="errors" v-if="!formIsValid">Please you enter all requested informations.</p>
<div class="actions">
<button>Send Message</button>
</div>
</form>
<!-- </div> -->
</template>
<script>
export default {
data(){
return {
name: '',
email: '',
message: '',
successMessage: true,
formIsValid: true,
}
},
methods: {
submitForm(){
this.formIsValid = true;
if (this.name === '' || this.email === '' || !this.email.includes('#') || this.message === '') {
this.formIsValid = false;
return;
} else {
fetch("https://vue-http-demo-8aa03.firebaseio.com/stone.json", {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({name: this.name,
email: this.email,
message: this.message}),
}).then((data)=>{
if (data.status === 200) {
this.successMessage = false;
this.name ='';
this.email ='';
this.message ='';
setInterval(function(){ this.successMessage=true;}, 3000);
setInterval(function(){ console.log(this.successMessage=true);}, 3000);
}
});
}
},
},
}
</script>
If you want to access valid scope for this, you need to use arrow function for setInterval:
setInterval(() => {
this.successMessage = true;
}, 3000);

How to create mysql table entry on form submission in CodeIgniter

I just need to insert data to table on form submission with the entered inputs.
my Controller,
function create_wish() {
$data = array(
'user_name' => $this->input->post('uname'),
'user_email' => $this->input->post('uemail'),
'user_message' => $this->input->post('umessage')
);
$this->model_wishes->createWish($data);
}
model,
function createWish($data) {
$sql = "INSERT INTO wishes (user_name, user_email, user_wish) VALUES (".$data.user_name.", ".$data.user_email.", ".$data.user_message.")";
$this->db->query($sql);
echo $this->db->affected_rows();
}
view,
<form method="post" action="<?php echo base_url() . "index.php/Welcome/create_wish"?>">
<div class="row">
<div class="form-group col-md-6">
<label for="post-name">Name</label>
<input autocomplete='name' type="text" class="form-control" id="uname" name="uname" required />
</div>
<div class="form-group col-md-6">
<label for="post-email">Email</label>
<input autocomplete='email' type="email" class="form-control" id="uemail" name="uemail" required/>
</div>
</div>
<div class="row">
<div class="form-group col-md-12 margin-b-2">
<label for="post-message">Message</label>
<textarea class="form-control" id="umessage" rows="5" name="umessage"></textarea>
</div>
</div>
<div class="row">
<div class="form-group col-md-12 text-left mb-0">
<button id="btn-create" type="submit" class="button-medium btn btn-default fill-btn">Post Wish</button>
</div>
</div>
</form>
Ajax,
$(document).ready(function () {
$('form').submit(function (event) {
var formData = {
'user_name': $('input[name=uname]').val(),
'user_email': $('input[name=uemail]').val(),
'user_wish': $('input[name=umessage]').val()
};
$.ajax({
type: 'POST',
url: 'http://localhost/CodeIgniterProj/index.php/create_wish',
data: formData,
dataType: 'json',
encode: true
})
.done(function (data) {
console.log(data);
});
event.preventDefault();
});
});
execution of above codes displays an error in console
POST http://localhost/CodeIgniterProj/index.php/create_wish 404 (Not Found)
XHR failed loading: POST "http://localhost/CodeIgniterProj/sender.php".
I tried to fix this and failed. Someone please let me know how to fix this issue, help me on this.
Your URL is missing the controller segment
you should call index.php/[controller]/[method]. Regarding the sender.php i cannot see any call to it. Maybe there are other forms in the markup.
Besides that, the model will not work as expected. Since you are dealing with an array you should change:
... VALUES (".$data.user_name.", ...)
to
...(VALUES (".$data["user_name"].", ...)
If you don't want to use the active record class, you should escape the values in your query.
https://www.codeigniter.com/user_guide/database/queries.html#escaping-queries
I hope it helps.
Use site_url in your ajax url , should be like this
$(document).ready(function () {
$('form').submit(function (event) {
var formData = $(this).serialize();
alert(formData);
$.ajax({
type: 'POST',
url: '<?=site_url('Welcome/create_wish');?>',
data: formData,
dataType: 'json',
}).done(function (data) {
console.log(data.id);
});
event.preventDefault();
});
});
Your controller should be like this :
function create_wish() {
$data = array(
'user_name' => $this->input->post('uname'),
'user_email' => $this->input->post('uemail'),
'user_message' => $this->input->post('umessage')
);
$insert_id = $this->model_wishes->createWish($data);
if($insert_id)
{
$response = array('status' => 'success');
}
else
{
$response = array('status' => 'error');
}
echo json_encode($response);
exit;
}
Your model method createWish should be like this ;
function createWish($data)
{
$this->db->insert('wishes', $data);
return $this->db->insert_id();
}

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');
}
}
});