(Backend repo is here: https://github.com/marcmajcher/sinatra-react-file-upload-demo-backend)
- clone https://github.com/learn-co-curriculum/phase-3-sinatra-react-project.git image-upload-backend
- cd image-upload-backend
- rm -rf .canvas .git .github
- bundle install
- git init; git add . ; git commit -m init
- rake server
- npx create-react-app image-upload-frontend
- cd image-upload-frontend
- npm start
- (optional) delete all the junk from the default react app: webvitals, logo, boilerplate App, etc
<h1>Upload File</h1>
<form onSubmit={uploadImage}>
<label htmlFor="file">File:</label>
<input type="file" name="image" onChange={handleImageChange} />
<button type="submit">Upload</button>
</form>
const [imageUrl, setImageUrl] = useState();
const [file, setFile] = useState();
function handleImageChange(e) {
setFile(e.target.files[0])
console.log(e.target.files[0])
}
function uploadImage(e) {
e.preventDefault();
const formData = new FormData();
formData.append('image', file);
fetch('http://localhost:9292/upload', {
method: 'POST',
body:formData,
})
.then((res) => res.json())
.then(json => setImageUrl(`http://localhost:9292/${json.url}`));
}
{ imageUrl ? <img src={imageUrl} alt={imageUrl} /> : '' }
- create folder in app: public/images
- in ApplicationCcntroller, set the public dir:
set :public_folder, 'app/public'
- and image directory:
set :image_dir, File.join(settings.public_folder, 'images')
post '/upload' do
if params[:image]
filename = params[:image][:filename]
tempfile = params[:image][:tempfile]
FileUtils.copy(tempfile, File.join(settings.image_dir, filename))
{status: "ok", url: "/images/#{filename}"}.to_json
else
{status: "error", message: "no file"}
end
end
Now when you submit a file through the form, the backend will grab the filename and the temporary file, copy the temp file to the images dir, and send back a url to access it!