Sending a CSV file using Node/Express - javascript

I'm building a front end tool that allows users to upload a CSV file to a certain end point. I use the HTML5 input="file"
Here is my JSX, I use the React Dropzone library:
<Dropzone
multiple={false}
onDrop={this.onDrop}
>
<div>
<input type="file" />
</div>
</Dropzone>
The onDrop function:
onDrop(acceptedFile) {
this.setState({ file: acceptedFile });
}
I grab that file and put it on my state. My submit function looks like this:
submitFile() {
const formData = new FormData();
formData.append('uploadCsv', this.state.file);
fetch('/api/person/uploadfile', {
body: formData,
method: 'POST'
});
}
It then goes through a few files for routing..
router.use('/person', require('./routers/personRoutes').default);
router.post('/uploadfile', fileUpload);
Then I run my fileUpload function:
export const fileUpload = post({
route: req => {
return `${BASE_URL}/v1/fileupload/persons`;
}
});
Here I have no idea what to do. Usually I just have to return a URL and everything works. req.body is just an empty object - {}. The error message I get back says:
Current request is not a multipart request
BUT. Something as simple as this does work:
<html>
<form action="http://localhost:9275/v1/fileupload/persons"
enctype="multipart/form-data" method="post">
<p>
Please specify a file, or a set of files:<br>
<input type="file" name="file" size="40">
</p>
<div>
<input type="submit" value="Send">
</div>
</form>
</html>
I've looked all over stack overflow and none of solutions have helped thus far :( the coworker who wrote the node stuff left so I'm alone on this

Related

Having trouble writing form input to a separate file

Currently I have a Next.js app with a form that looks like this:
import React from 'react'
function Form() {
return (
<div>
<form action="/api/newfile" method="post">
<label htmlFor="project">project Name</label>
<textarea width={100} height={100} type="text" name="project" required />
<button type="submit">Submit</button>
</form>
</div>
)
}
export default Form
With help from How to create file from /api in NextJS? I was able to get an API function set up that my form can interact with:
import fs from 'fs';
export default async function handler(req, res) {
const {
method,
body,
} = req
try {
switch (method) {
case 'POST':
fs.writeFileSync('./pages/api/newfilewithoutanextension', JSON.stringify(body))
break
default:
res.setHeader('Allow', ['GET', 'POST'])
res.status(405).end(`Method ${method} Not Allowed`)
}
return res.status(200).json({ message: 'Success' })
} catch (error) {
return res.status(500).json(error)
}
}
I fire up the app and at the /form page my input looks like this:
function() {
echo my form input
}
I am able to write my new file to disk without the file extension (this was correct by design), however the response is written in JSON. It looks like this:
{"project":"function() {\r\n echo \"my form input\"\r\n}"}
I need the newly generated file contents to look like that of my form input.
I have tried replacing the JSON.stringify(body) but seem to get everything but the response I need.

How prevent reload after post request?

I am trying to make a post request to the server and do something with the response. Things seem to work on the server-side. The problem is that the page reloads upon completion of the response and I cannot do anything with the response.
The common suggestions are using button or preventDefault. These suggestions do not solve the problem: as you can see below, the input type is button (not submit) and preventDefault() on the event does not work.
Does anyone have an idea about what I am missing?
<form id="modelCodeForm">
<label for="codehere"></label>
<div id="modelAreaDiv">
<textarea id="modelArea" cols="60" rows="20">
stuff
</textarea>
<br>
<input id="submitUserModel" type="button" value="run on server">
</div>
</form>
function initializeUserModel(){
let model = document.getElementById("modelArea").value;
fetch('http://localhost:8080/', {
method: 'post',
headers: {'Content-Type': 'text/plain'},
body: model
})
.then(response => response.json())
.then(data => {
console.log(data);
}).then(console.log("received!"))
}
I got to the bottom of this. It turns out that the problem was due to VS Live Server which was detecting a change in the folder and hot-loading the app. The change was due to the backend, in the same folder, saving a log. Really silly thing to miss...
If you want to trigger your function when the form is submitted then you can use the "onsubmit" event listener available on HTML forms.
So you would do onsubmit="initializeUserModel(event)". You pass it the event object so you can call event.preventDefault() in the function and stop the page from reloading.
Change your input to type="submit" (or make it a button of type="submit") or the form submission won't be triggered.
<form id="modelCodeForm" onsubmit="initializeUserModel(event)">
<label for="codehere"></label>
<div id="modelAreaDiv">
<textarea id="modelArea" cols="60" rows="20">Stuff</textarea>
<br />
<input id="submitUserModel" type="submit" value="run on server" />
</div>
</form>
function initializeUserModel(event) {
event.preventDefault();
let model = document.getElementById("modelArea").value;
fetch("http://localhost:8080/", {
method: "post",
headers: { "Content-Type": "text/plain" },
body: model,
})
.then((response) => response.json())
.then((data) => {
console.log(data);
})
.then(console.log("received!"));
}

preventDefault in JS not working when fetch API upload files

I have been trying to create a simple web app where you can post images and a little description. It is for an Instagram Clone project. I am using multer and express on the backend to parse the body and the file, and it works perfectly fine. The problem is on the frontend. I provide a form where you put name, description and the image to upload, then with the Fetch API I send the body to my api on the backend.
I noticed that the page reloads every time I submit the form despite the use of event.preventDefault() and event.stopPropagation() for the form sumbit event.
In addition, I have realised that it does so only when also uploading the file, in fact, if I leave the name and description alone, it doesn't reload the page, whereas if I live the file upload in there it just reloads it.
Is this a bug of the fetch API or am I not considering something?
Here's the code on the frontend that handles the fetch request to my api:
const instaForm = document.getElementById("post-pic");
instaForm.addEventListener("submit", (event) => {
event.preventDefault();
event.stopPropagation();
let instaFormData = new FormData(instaForm);
let url = `${baseUrl}/create-insta`;
fetch(url, {
method: "POST",
body: instaFormData,
})
.then((data) => data.json())
.then((response) => {
instaForm.reset();
console.log(response);
})
.catch((err) => console.error(err));
});
Consider that if I leave the input for the file blank, the page doesn't reload so it is definitely a problem with the file upload.
For now, for debugging my API is sending back a simple "Received" response and nothing else.
HTML Form
<form method="POST" id="post-pic" enctype="multipart/form-data">
<input
type="text"
id="name"
name="name"
placeholder="Enter a name..."
/>
<textarea
name="description"
id="description"
rows="10"
placeholder="A short description..."
></textarea>
<input type="file" id="picture" name="insta" />
<button id="publish" type="submit">Publish</button>
</form>
You should catch the event when clicking on the form button.
Try this:
<form method="POST" id="post-pic" enctype="multipart/form-data">
<input
type="text"
id="name"
name="name"
placeholder="Enter a name..."
/>
<textarea
name="description"
id="description"
rows="10"
placeholder="A short description..."
></textarea>
<input type="file" id="picture" name="insta" />
<button id="publish" type="button">Publish</button>
</form>
JS Script:
const instaForm = document.getElementById("post-pic");
const buttonForm = document.getElementById("publish");
buttonForm.addEventListener("click",(event) => {
event.preventDefault();
let instaFormData = new FormData(instaForm);
let url = `${baseUrl}/create-insta`;
fetch(url, {
method: "POST",
body: instaFormData,
})
.then((data) => data.json())
.then((response) => {
instaForm.reset();
console.log(response);
})
.catch((err) => console.error(err));
});
}
I hope it could help you.
Regards.

Passing JSON to login.php on XAMPP returns a 405

I'm creating a simple fetch post request from my <form> to a login.php file on my local server using XAMPP. The index.html index.js login.php files are all in the root directory.
My index.js is the below:
const myForm = document.getElementById("myForm");
myForm.addEventListener("submit", function(e) {
e.preventDefault();
const formData = new FormData(this);
fetch("login.php", {
method: "post",
body: formData
})
.then(response => {
return response.text();
})
.then(text => {
console.log(text);
})
.catch(error => {
console.log(error);
});
});
My index.html is:
<form class="form" id="myForm" action="">
<label for="username">Username:</label>
<input type="text" name="username" id="username" />
<label for="password">Password:</label>
<input type="password" name="password" id="password" />
<button type="submit">Login</button>
</form>
And my login.php is:
<?php
var_dump($_POST);
?>
I simply just want to log to the console the responses to check the output and test my form, however when I fill out the form I get:
index.js:7 POST http://127.0.0.1:5501/login 405 (Method Not Allowed)
So this makes me think I need to set certain permissions on my Apache server. But I don't exactly know how to do this.
Or perhaps I'm missing something else. Can someone point me in the right direction?
It work on the xampp server http://127.0.0.1/example/index.html in htdocs folder

I want to submit a form and update the values from the form (Mysql result) without refreshing the whole page

as the title says, I want to submit a form and update the values from the form (Mysql result) without refreshing the whole page.
See Image 1, I want if I press the blue button that the values updated.
Can someone help me?
Thanks.
If you are willing to use newer apis like Promise and fetch, it's super easy and neat.
foo.submit.addEventListener("click", (e) => {
e.preventDefault();
fetch("YOUR_URL", {
method: 'POST',
body: new URLSearchParams({
name: foo.user_name_value,
email: foo.user_mail.value
})
}).then(response => {
return response.json() // assume returning data is in json format, otherwise .text() could be used
}).then(data => {
// deal with return data
}).catch(err => {
// deals with errors
})
})
<form name="foo">
<div>
<label for="name">Name:</label>
<input type="text" id="name" name="user_name">
</div>
<div>
<label for="mail">E-mail:</label>
<input type="email" id="mail" name="user_mail">
</div>
<div>
<button name="submit" type="submit">Send your message</button>
</div>
</form>
Older method XHR shares same idea, but requires a bit more code. You may use axios or so to simplify the process.

Categories

Resources