netlify form submission not showing file on the back end, all other fields are showing up but not the file upload - netlify

Even though it is mostly from the netlify site, I can't seem to figure out why the file upload doesn't work. What I get on the other end is all the fields, but the file upload comes back blank with no error in the console. Looked at videos and online instructions and don't see what the difference is
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Contact</title>
<script src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone#6.15.0/babel.min.js"></script>
</head>
<body>
<!-- A little help for the Netlify post-processing bots -->
<form name="contact" netlify hidden>
<input type="text" name="name" />
<input type="text" name="CompanyName" />
<input type="text" name="Address" />
<input type="text" name="PrimaryContact" />
<input type="text" name="SecondaryContact" />
<input type="email" name="email" />
<textarea name="message"></textarea>
<input type="file" name="myFile"/>
</form>
<div id="root"></div>
<script type="text/babel">
const encode = (data) => {
return Object.keys(data)
.map(key => encodeURIComponent(key) + "=" + encodeURIComponent(data[key]))
.join("&");
}
class ContactForm extends React.Component {
constructor(props) {
super(props);
this.state = { name: "",CompanyName:"",Address:"",PrimaryContact:"", SecondaryContact:"", email: "", message: "" , myFile:""};
}
/* Here’s the juicy bit for posting the form submission */
handleSubmit = e => {
fetch("/", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: encode({ "form-name": "contact", ...this.state })
})
.then(() => alert("Success!"))
.catch(error => alert(error));
e.preventDefault();
};
handleChange = e => this.setState({ [e.target.name]: e.target.value });
render() {
const { name,CompanyName, Address, PrimaryContact,SecondaryContact,email, message,myFile } = this.state;
return (
<form onSubmit={this.handleSubmit} data-netlify-recaptcha="true" data-netlify="true">
<p>
<label>
Your Name: <input type="text" name="name" value={name} onChange={this.handleChange} required/>
</label>
</p>
<p>
<label>
Company Name: <input type="text" name="CompanyName" value={CompanyName} onChange={this.handleChange} />
</label>
</p>
<p>
<label>
Address: <input type="text" name="Address" value={Address} onChange={this.handleChange} />
</label>
</p>
<p>
<label>
Primary Contact: <input type="text" name="PrimaryContact" value={PrimaryContact} onChange={this.handleChange} />
</label>
</p>
<p>
<label>
Secondary Contact: <input type="text" name="SecondaryContact" value={SecondaryContact} onChange={this.handleChange} />
</label>
</p>
<p>
<label>
Your Email: <input type="email" name="email" value={email} onChange={this.handleChange} />
</label>
</p>
<p>
<label>
Ticket Discription: <textarea name="message" value={message} onChange={this.handleChange} />
</label>
</p>
<p>
<input type="file" name="myFile" placeholder="Upload File" />
</p>
<p>
<button type="submit">Send</button>
</p>
</form>
);
}
}
ReactDOM.render(<ContactForm />, document.getElementById("root"));
</script>
</body>
</html>

I had a similar issue and was able to solve it using this checklist from the Netlify community:
6. Make sure that you POST your form request (not GET) with a Content-Type of application/x-www-form-urlencoded in most cases. However, if and only if you are submitting the form with a file upload then the Content-Type needs to be multipart/form-data instead.
from: [Common Issue] Form problems, form debugging, 404 when submitting
Moving to a different Content-Type solved a similar issue for me. Then again I'm not using fancy Javascript/Ajax form submission so all it took was to add an enctype="multipart/form-data" attribute to my form tag. In your case it will require reworking your encode function.

I also had a similar issue.
Removing the headers option from the fetch() function did it for me.
Ex:
fetch("/", {
method: "POST",
// headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: encode({ "form-name": "contact", ...this.state })
})

Related

Angular 13 - Data is accessible inside component, but does not show on the html page

So, I am learning Angular right now, and tried doing a CRUD Application. Almost everything works, except when trying to get data using ID, I can access all the data in the component.ts file, but the same is not rendered into html file. Here is what I have tried :-
edit-to.component.ts
export class EditTodoComponent implements OnInit {
private tid: number = 0;
public Todo:TodoModel= null ;
public desc:string='';
public title:string='';
public id:number;
constructor(private route: ActivatedRoute, private http:HttpClient) { }
ngOnInit(): void {
this.route.paramMap.subscribe(all_params =>{
this.tid = parseInt(all_params.get('id'))
//console.log( all_params.get('id'))
//console.log( this.tid );
});
this.getTodoFromId(this.tid)
}
getTodoFromId(id){
//console.log("id="+id)
this.http.get<{data: any}>('http://localhost:3000/api/todos/get_todo_from_id/'+id).subscribe((data) =>{
console.log("response in angular= \n");
this.Todo = data[0]
console.log(this.Todo.todo_title) //-> This one works
}
editOnSubmit(form:NgForm){
//something here
}
edit-todo.component.html
<div class="col-md-12">
<form (ngSubmit)="editOnSubmit(todoForm)" #todoForm="ngForm">
<input type="text" class="form-control" id="todo_id" [(ngModel)]="id" name="todo_id" value="1">
<div class="mb-3">
<label for="todo_title" class="form-label">Title</label>
<input type="text" class="form-control" id="todo_title" [(ngModel)]="title" name="title" value="{{ Todo.todo_title}}"> //-> This one does not work.
</div>
<div class="mb-3">
<label for="label" class="form-label">Description</label>
<textarea class="form-control" id="todo_description" [(ngModel)]="desc" name="desc" ></textarea>
</div>
<button type="submit" class="btn btn-success">Edit To Do</button>
</form>
</div>
</div>
Separating out,
from edit-to.component.ts :-
console.log(this.Todo.todo_title) works
but from edit-todo.component.html
<input type="text" class="form-control" id="todo_title" [(ngModel)]="title" name="title" value="{{ Todo.todo_title}}"> does not work
it's because you have a ngModel and a value configured on same input field
in this situation the ngModel have priority on value attribute
to fix it you can initialize title in ngOnInit
this.title = this.Todo.todo_title;
in your case you wait reply from http request so the initialization after hte http reply :
getTodoFromId(id){
this.http.get<{data: any}>('http://localhost:3000/api/todos/get_todo_from_id/'+id).subscribe((data) =>{
console.log("response in angular= \n");
this.Todo = data[0]
this.title = this.Todo.todo_title;
console.log(this.Todo.todo_title);
}
Define a property of type BehaviorSubject.
isAvailableData = new BehaviorSubject<boolean>(true);
Then where you subscribe the data set it to true.
getTodoFromId(id){
//console.log("id="+id)
this.http.get<{data: any}>('http://localhost:3000/api/todos/get_todo_from_id/'+id).subscribe((data) =>{
console.log("response in angular= \n");
this.Todo = data[0];
this.isAvailableData.next(true);
console.log(this.Todo.todo_title) //-> This one works
}
after that in your HTML add ngIf to col-md-12 div:
<div class="col-md-12" *ngIf="(isAvailableData | async)">
<form (ngSubmit)="editOnSubmit(todoForm)" #todoForm="ngForm">
<input type="text" class="form-control" id="todo_id" [(ngModel)]="id" name="todo_id" value="1">
<div class="mb-3">
<label for="todo_title" class="form-label">Title</label>
<input type="text" class="form-control" id="todo_title" [(ngModel)]="title" name="title" value="{{ Todo.todo_title}}"> //-> This one does not work.
</div>
<div class="mb-3">
<label for="label" class="form-label">Description</label>
<textarea class="form-control" id="todo_description" [(ngModel)]="desc" name="desc" ></textarea>
</div>
<button type="submit" class="btn btn-success">Edit To Do</button>
</form>
Also you made a mistake in your form the input should be like below:
And there is no need to define a property for id, title, ...
These are the properties of todo object
<label for="todo_title" class="form-label">Title</label>
<input type="text" class="form-control" id="todo_title" [(ngModel)]="Todo.todo_title" name="todo_title" #todo_title="ngModel">

How to integrate 2checkout with reactjs and nodejs?

I am trying to integrate 2checkout API in my reactjs &nodejs project.I reffered the documents which 2co provided.I created an account and in that webhooks&API i have "Merchant Code" and "Secret Key" but there is no "Publishable key" and "Private Key" Why?
what i have is:
render = () => {
return(
<form id="myCCForm" onSubmit={this.Submit}>
<input
id="token"
name="token"
type="hidden"
value=""
></input>
<div>
<label>
<span>Card Number</span>
</label>
<input
id="ccNo"
type="text"
size="20"
value=""
autocomplete="off"
required
/>
</div>
<div>
<label>
<span>Expiration Date (MM/YYYY)</span>
</label>
<input
type="text"
size="2"
id="expMonth"
required
></input>
<span> / </span>
<input
type="text"
size="2"
id="expYear"
required
></input>
</div>
<div>
<label>
<span>CVC</span>
</label>
<input
id="cvv"
size="4"
type="text"
value=""
autocomplete="off"
required
></input>
</div>
<input type="submit" value="Submit Payment"></input>
</form>
)}
submit=()=>{
let args = {
sellerId: "",//gave merchant code here
publishableKey: "",//as there is no publishable key what will give here?
ccNo: "",
cvv: "",
expMonth: "",
expYear: ""
};
window.TCO.loadPubKey("sandbox", () => {
window.TCO.requestToken(args).then(data => {
console.log("data");
});
});
How can i resolve this problem?

How to use endpoint inside another endpoint in express node js

I am just stuck in a problem and also don't know whether the question is correct or not.
I am working on a node express js, using ejs templating engine.
I have created certain endpoints (say login(POST) endpoint) which are generic endpoints.
Now I want to create a new application which uses should use these endpoints and render the view according to the result of these endpoints.
Lets say I have a generic endpoint for login
router.post('/user/login', function (req, res) {
var userLoginId = req.body.username;
var currentPassword = req.body.password;
UserLogin.findOne({userLoginId: userLoginId, currentPassword: currentPassword}, function (err, usr) {
if (err) {
console.log('Error in User login');
console.log(err);
res.status(500).type('application/problem+json').send();
} else {
if (!usr) {
console.log('Please enter valid username and password');
res.status(404).type('application/problem+json').send();
} else {
res.type('application/json').status(200).send(usr);
}
}
});
});
And I am using this login.ejs file
<div class="container panel panel-primary">
<h2 class="h2 text-center">Login</h2>
<form class="form-horizontal" name="loginForm" method="post" action="/user/login">
<div class="form-group">
<label for="username" class="col-sm-offset-2 col-sm-2 control-label">UserName</label>
<div class="col-sm-4">
<input type="text" name="username" class="form-control" id="username" placeholder="username">
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-offset-2 col-sm-2 control-label">Password</label>
<div class="col-sm-4">
<input type="password" name="password" class="form-control" id="password" placeholder="Password">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-4">
<button type="submit" class="btn btn-primary btn-">Sign in</button>
</div>
</div>
</form>
</div>
Now I want to use this code and want to login to the system.
If the user login is successful I want to redirect to dashboard page else same login page.
On executing this code the api returns me the JSON response and from this response how can I decide to whether to redirect on dashboard page or login page.
Please help if more input is needed please put a comment.
I would instead of doing a form request to login, do a AJAX request to login and then use something like jQuery to do the AJAX request and response. Alternatively you could do something like the following.
router.get('/login', function(req, res){
res.render('login', {});
})
router.post('/login', function (req, res) {
var userLoginId = req.body.username;
var currentPassword = req.body.password;
UserLogin.findOne({userLoginId: userLoginId, currentPassword: currentPassword}, function (err, usr) {
if (err) {
console.log('Error in User login');
console.log(err);
// res.status(500).type('application/problem+json').send();
res.status(500).render('login', { error : 'Error finding password'})
} else {
if (!usr) {
console.log('Please enter valid username and password');
// res.status(404).type('application/problem+json').send();
res.status(404).render('login', { error : 'Please enter valid username and password'})
} else {
res.redirect('/dashboard');
}
}
});
});
For the login.ejs file i would conditionally render the error.
<!DOCTYPE html>
<html>
<body>
<div class="container panel panel-primary">
<h2 class="h2 text-center">Login</h2>
<%if (locals.error) { %>
<%= error %>
<% } %>
<form class="form-horizontal" name="loginForm" method="post" action="/user/login">
<div class="form-group">
<label for="username" class="col-sm-offset-2 col-sm-2 control-label">UserName</label>
<div class="col-sm-4">
<input type="text" name="username" class="form-control" id="username" placeholder="username">
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-offset-2 col-sm-2 control-label">Password</label>
<div class="col-sm-4">
<input type="password" name="password" class="form-control" id="password" placeholder="Password">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-4">
<button type="submit" class="btn btn-primary btn-">Sign in</button>
</div>
</div>
</form>
</div>
</body>
</html>

How to update a record using Sequelize?

I am trying to update the records form a table by using Sequelize.
Unfortunately, the id of the event I am trying to update seems to be undefined. How can I send it correctly?
The block of code I have in my controller looks like this:
router.get('/edit/:eventid', function(req, res) {
var eventid = req.params.eventid;
Event.findById(req.params.eventid).then(function(event) {
eventid= event.eventid;
title= event.title;
description= event.description;
availabletickets=event.availabletickets;
date= event.date;
newDate= date.toString();
newdate= newDate.substring(0,21);
console.log(eventid);
}) .then(function() {
res.render('eventEdit', {
eventid: eventid,
pagetitle: ' Edit Event',
title: title,
description:description,
availabletickets:availabletickets,
newdate: newdate,
});
})
.catch(function(error) {
res.render('error', {
error: error
});
});
});
router.post('/edit', function(req, res){
var eventid = req.body.eventid;
var title = req.body.title;
var description = req.body.description;
var availabletickets= req.body.availabletickets;
var date = req.body.date;
console.log( eventid); //this returns undefined.
console.log('title, description, availabletickets, date);
const newData = {
title: title,
date: date,
description: description,
availabletickets: availabletickets
};
Event.update(
newData,
{
where:{
eventid:eventid
}
}
).then(function() {
console.log("Event updated");
res.redirect('/events');
}).catch(e => console.error(e));
});
Although, the HTML file,where the user introduces the values when editing the events, looks like this:
<div class="container">
<h2><%= pagetitle %> </h2>
<form method="post" action="/events/edit">
<div class="container">
<div class="col-md-12 ">
<div class="row">
<div class="col-md-12 ">
<input class="form-control" type="text" name="title" id="title" value="<%= title %>" placeholder="Titlu Eveniment" required="true">
<p style="color:#8B0000;"><small>*This field is mandatory</small></p>
<textarea rows=7 class="form-control" type="text" name="description" id="description" placeholder="Descriere Eveniment"><%= description %></textarea> <br>
<input class="form-control" type="text" name="availabletickets" id="availabletickets" value="<%= availabletickets %>"> <br>
<label> Data:<%= newdate %> </label> <br/>
<label>Cahnge event date:</label>
<input class="form-control" type="date" name="date" id="date" style="width:190px;" ><br>
<button class="btn" id="addValue" style="background-color:#8B0000; color:white;">Save</button>
<button class="btn btn-warning">Cancel</button>
</div>
</div>
</div>
</div>
</form>
</div>
You get the eventid as undefined because req.body doesn't contain the eventid (it's not passed from the client side). To pass it from the client side you have to add an input having the name="eventid" attribute.
In the EJS template you need to render the eventid value as a hidden input (<input type="hidden" ...)
You can do that by added in your form this line:
<input type="hidden" value="<%= eventid %>" name="eventid" />
This is the updated form code:
<div class="container">
<h2><%= pagetitle %> </h2>
<form method="post" action="/events/edit">
<input type="hidden" value="<%= eventid %>" name="eventid" />
<div class="container">
<div class="col-md-12 ">
<div class="row">
<div class="col-md-12 ">
<input class="form-control" type="text" name="title" id="title" value="<%= title %>" placeholder="Titlu Eveniment" required="true">
<p style="color:#8B0000;"><small>*This field is mandatory</small></p>
<textarea rows=7 class="form-control" type="text" name="description" id="description" placeholder="Descriere Eveniment">
<%= description %>
</textarea>
<br>
<input class="form-control" type="text" name="availabletickets" id="availabletickets" value="<%= availabletickets %>">
<br>
<label> Data:
<%= newdate %>
</label>
<br/>
<label>Cahnge event date:</label>
<input class="form-control" type="date" name="date" id="date" style="width:190px;">
<br>
<button class="btn" id="addValue" style="background-color:#8B0000; color:white;">Save</button>
<button class="btn btn-warning">Cancel</button>
</div>
</div>
</div>
</div>
</form>
</div>

How to use same the form for POST and PUT requests using ejs?

What I'm trying to do is the following:
routes
router.route('/new')
.get(function (req, res) {
var method = ''
res.render('users/new.ejs', { method: method });
});
router.route('/edit/:user_id')
.get(function (req, res) {
var method = '<input type="hidden" name="_method" value="put" />'
var user = User.findById(req.params.user_id, function (err, user) {
if(!err) {
return user;
}
});
res.render('users/edit.ejs', {
method: method
});
});
_form.ejs
<form accept-charset="UTF-8" action="/api/v1/users" method="post">
<%- method %>
<div class="field">
<label for="firstName">First Name</label><br>
<input id="firstName" name="firstName" type="text" />
</div>
<div class="field">
<label for="age">Age</label><br>
<input id="age" name="age" type="number" />
</div>
<div class="field">
<label for="annualIncome">Annual Income</label><br>
<input id="annualIncome" name="annualIncome" type="number" />
</div>
<div class="field">
<label for="email">Email</label><br>
<input id="email" name="email" type="text" />
</div>
<div class="field">
<label for="riskTolerance">Risk Tolerance</label><br>
<input id="riskTolerance" name="riskTolerance" type="number" />
</div>
<div class="actions">
<input type="submit" value="Submit">
</div>
</form>
So, I want to do it like in Rails where you can use the same form for both creating and editing a model. So, I wanted to say that it is a PUT request when the form is used for editing.
Is this the appropriate way to do it?
Rather than embedding html in your routing code, you could just use a conditional statement in the ejs template
routes
res.render('users/edit.ejs', {
put: true
});
_form.ejs
<form accept-charset="UTF-8" action="/api/v1/users" method="post">
<%if (put) { %>
<input type="hidden" name="_method" value="put" />
<% } %>
<div class="field">
<label for="firstName">First Name</label><br>
<input id="firstName" name="firstName" type="text" />
</div>
...
</form>

Resources