I'm trying to read a csv file using flask and then display it through react (The display part should be compulsorily done through react). I'm stuck at the return part of js file.
This is the flask(.py)code:
from flask import Flask,render_template,request
import os
import pandas as pd
app=Flask(__name__)
app.secret_key="123"
app.config["UPLOAD_FOLDER1"]="static/csv"
@app.route("/upload",methods=['GET','POST'])
def upload():
return render_template("UploadCsv.html")
@app.route("/display",methods=["GET","POST"])
def display():
upload_file = request.files['upload_csv']
if upload_file.filename != '':
file_path = os.path.join(app.config["UPLOAD_FOLDER1"], upload_file.filename)
upload_file.save(file_path)
data=pd.read_csv(file_path,sep=",")
return render_template("CsvContent.html",data=data.to_html(index=False))
if __name__=='__main__':
app.run(debug=True)
And here are the two HTMLs used in the .py file above: UploadCsv.html
<html>
<head>
<title>Upload CSV File</title>
</head>
<body>
<div style="margin-top:70px">
<form method="POST" action="http://127.0.0.1:5000/display" enctype="multipart/form-data">
<h3 >Upload CSV File</h3>
<div >
<label>Browse CSV File</label>
<input type="file" name="upload_csv">
</div>
<div >
<button type="submit" >Upload CSV</button>
</div>
</form>
</div>
</body>
</html>
CsvContent.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSV File</title>
</head>
<body>
<h2>Here's your uploaded CSV file :</h2>
{{data|safe}}
</body>
</html>
This successfully reads and displays the CSV file completely through Flask. Now, here's the catch, I have to integrate react too. And this is where I'm messing up. Here's my React code, if it helps.
const[csvupload,setCsvUpload] = useState()
useEffect(()=> {
fetch('http://127.0.0.0:5000/display',{
'method':'POST',
headers: {
'Content-Type' : 'application/json'
}
})
.then(resp => resp.json())
.then(resp => setCsvUpload(resp))
.catch(error => console.log(error))
},[])
return (
<Fragment>
<div className="upload" >
Upload Your CSV File
<Row md={12}>
<Col md={6} className="body-upload">
<input type="file" accept=".csv" onChange={handleFileUpload} multiple />
<button onClick={modalOpen}> UPLOAD </button>
</Col>
</Row>
{csvupload.map(csv =>{
return(
(**What should be here?**)
<div>
</div>
)
})}
</div>
</Fragment>
);
};
export default UploadFile;
How can I return the CSV file through react? I am using fetch here, is it even the right method? What should I put inside the return method so that when I upload the csv, it should read the file, store in "static/csv" (as given in the flask code) and display the file below before clicking Upload. I know its a long question, but please help. Any kinda help would be appreciated and I'm willing to provide information required.
CodePudding user response:
Few things you can do:
The call you make to
/display
has no payload being sent. If that is the case, you can change to a GET callParsing the csv directly on the frontend can be resource intensive depending on the content. It would be better for you to parse it on the backend itself and then send the JSON to react that looks like the following (or any other structure based on your needs):
// option1
{
row1: [col1, col2],
row2: [col1, col2]
}
// or send an array of rows
// option2
[[col1, col2], [col1, col2]]
- Once you have the parsed csv content you can use it like this on react:
// option 2
{
csvupload.map((row) => {
// you can format as per your requirement
// col1=row[0] and col2=row[1]
return <div>{row}</div>;
})
}
// option 1
{
Object.keys(csvupload).map((rowIndex) => {
// you can format as per your requirement
// col1=csvupload[rowIndex][0] and col2=csvupload[rowIndex][1]
return <div>{csvupload[rowIndex]}</div>;
})
}
Personally, I feel option 1 would be better. But you can change this structure based on whatever best fits your requirements.
Edit: based on comment
- This answer might help for parsing what to do,
- and the docs for the function used further info in docs
- In option1, Object.keys(csvupload) returns an array of keys. rowIndex is an index of this array. When passed into the csvupload JSON, it returns the column array
[col1, col2]
- In option2, row is the array of columns in that specific row
[col1, col2]
(same as option1) - Both options give the same result. It's just a difference of how you are accessing the value