Hey I am creating an Upload Image system. But when my backend returns the imagePath and I manage the path in a React useState on the src, the image is not showing, and the console throw the following error:
This is my package.json in React:
{
"name": "client",
"version": "0.1.0",
"private": true,
"proxy": "http://localhost:3000",
"dependencies": {
"@testing-library/jest-dom": "^5.16.1",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
"axios": "^0.25.0",
"bootstrap": "^5.1.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "5.0.0",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
My backend is running on port 3000 and React is running on port 3001.
Here is my React code:
import { useState } from "react";
import axios from 'axios';
import {Message} from './Message.js';
import {ProgressBar} from './ProgressBar.js';
export const App = () => {
const [file, setFile] = useState('');
const [fileName, setFileName] = useState('Choose a file');
const [uploadedFile, setUploadedFile] = useState({});
const [message, setMessage] = useState('No file uploaded');
const [uploadPercentage, setUploadPercentage] = useState(0);
const handleChange = (e) => {
setFile(e.target.files[0]);
setFileName(e.target.files[0].name);
}
const handleSubmit = async (e) => {
e.preventDefault();
const formData = new FormData();
formData.append('file', file);
try {
const res = await axios.post('/uploadImage', formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: ProgressEvent => {
setUploadPercentage(
parseInt(
Math.round( (ProgressEvent.loaded * 100) / ProgressEvent.total )
)
);
setTimeout(() => {
setUploadPercentage(0);
}, 10000);
}
})
const {fileName, filePath} = res.data;
//return from res.data = /Users/rodrigoroldan/Desktop/Programacion/ImageUploader/client/public/uploads/sktwif5gkyvo0o92.png
setUploadedFile({fileName, filePath});
setMessage('File Uploaded');
} catch (error) {
if(error.response.status === 500){
setMessage('There was a problem with the server');
} else{
setMessage(error.response.data.msg);
}
}
}
return (
<div className="container text-center d-flex flex-column">
<h1 className="display-2">Image uploader</h1>
{message && <Message msg={message}/> }
<form className="form d-flex flex-column" onSubmit={handleSubmit}>
<ProgressBar percentage={uploadPercentage} />
<input type="file" accept="image/*" name="image" onChange={handleChange}/>
<button className="btn btn-primary" onClick={handleSubmit}>Upload</button>
</form>
<label className="label">
{fileName}
</label>
{
uploadedFile
&&
<div className="row mt-5">
<div className="col-md-6 m-auto">
<img src={uploadedFile.filePath} alt={uploadedFile.fileName} style={{width:'100%'}} />
</div>
</div>
}
</div>
);
}
Thanks!
CodePudding user response:
I can see on the screenshot that your code seek a path in your react app while it must search in your backend (port 3000). It means that the path of your file is bad.
You must stock and expose the image in your backend server and then display the image by transforming this line:
<img src={uploadedFile.filePath} alt={uploadedFile.fileName} style={{width:'100%'}} />
to
<img src={`${process.env.REACT_APP_BACKEND_URI}${uploadedFile.filePath}`} alt={uploadedFile.fileName} style={{width:'100%'}} />
with REACT_APP_BACKEND_URI as an environment variable (in your case for the moment it's localhost:3000) and uploadedFile.filePath the path where you save your image in the backend instead of the local file location (It seems to be the file location on your computer and not the location on the server). When you done this the html is going to search for the location of the file with your filepath but in the backend, then it will be displayed if it exists, otherwise you'll have a 404 error.
CodePudding user response:
I solved changing the filePath with these lines:
const filePathSplit = filePath.split('/');
const newNameFile = filePathSplit[filePathSplit.length - 1]
const newFilePath = `/uploads/${newNameFile}`
And my img tag is:
<img src={uploadedFile.newFilePath} alt={uploadedFile.fileName} style={{width:'100%'}} />

