Hamed, huge thanks for the awesome tutorials! You didn't just whip up a useful component, but you also broke it down and threw in some great tips. Keep the cool stuff coming our way!
This is honestly one of the greatest things on the internet. You teach very well. Thanks so much, I was trying to do something exactly like this and couldn't find anything until this.
Thanks for amazing lesson! I have a question - I am unable to access the preview property in Files object in the JSX. The error that I am getting is "Property 'preview' does not exist on type 'File' " Have done the exact same approach that you have mentioned in the video. just that my project supports react typescript.
@@mayank19saxena Or you could use a custom type for this. First define the custom type like this type UploadedFile = File & { preview: string }; and then, where you have the useState do something like this const [files, setFiles] = useState([]);
What if we need to get all the urls for multiple images? Atm, we upload multiple images to cloudinary but only get back one url for a single image. Ideally, would like to have array of image urls which then can be sent to backend api to store in some DB. I've tried to store image urls via state after getting back data but when i access it, the state array is not yet populated with the urls.
You'd need to loop through your form files and upload them one by one to cloudinary, get the url, maybe push it to an array, and at the end write to your database.
@@hamedbahram Yea I tried that but the issue is that it doesnt wait for the state array to be populated hence just empty array. const handleSubmit = async (e) => { e.preventDefault() if (!files?.length) return console.log('files:', files) files.forEach(async (file) => { const formData = new FormData() formData.append('file', file) formData.append('upload_preset', presetKey) axios .post( `api.cloudinary.com/v1_1/${cloudName}/image/upload`, formData ) .then((res) => setImgUrls((prevVal) => [...prevVal, res.data])) .catch((err) => console.error(err)) }) //does NOT WAIT until the loop is completely done above to populate the state array console.log('Sending img url to my backend server...') console.log('imgUrls', imgUrls)//[ ] }
Hey man real thanks for this insightful video about react dropzone and cloudinary. I have a question can we upload multiple files at the same time using cloudinary
Hi, what if I wanted to save these files to a local database (i.e., a folder on my desktop) would that be possible? I wanted to use this to for an MVP I'm creating: - Drag and drop files, save to local folder (mock database) using React Dropzone - Run a python code that goes into that folder and executes code
Saving files locally won't really work once you deploy your app to serverless platforms like Vercel. You should use a real data base or a media cloud provider to store your files. You can look into this for file storage => www.bytescale.com
Not out of the box, but I guess you can implement it using a custom validator. Something like this: ``` function imageDimensionValidator(file) { const image = new Image() image.onload = function () { console.log(this.width, this.height) } image.src = URL.createObjectURL(file) } ```
I'm not sure if I understand the question. Can you explain what you mean by saving the files until work is finish without a database? where do you want to save the files? In the video I save the files in my cloud storage (Cloudinary) and get a URL back which I can write to my database later.
Hi thanks for the tutorial! I am also using this method of having a separate state for the selected files so as to allow removal of files and selecting files one by one. However I have one issue - when I use the maxFiles property, this property is tied to the acceptedFiles from react-dropzone, which means that if my maxFiles = 3, and I select one by one, I can still end up selecting more than 3, because acceptedFiles "refreshes" each time we select a file. Do you have a solution for this? Thanks again!
You can pass a custom validator function where you can check the number of current files in your local state and throw an error if it exceeds your maximum number of files.
@@hamedbahram Thanks for the quick reply! Yes I did see that, but I am not able to access the number of files that the user is about to select. For example let's say max is 3. If the user already selected 2, and is now about to select another 2, that shouldn't be allowed, but if he is about to select 1 it should be allowed. However interestingly, I was able to set maxFiles dynamically like 3-files.Length (where files is my custom useState for the files). That worked like a charm!
It seems i have fixed this issue, but another one popped,and trying to solve this with no result. any idea how to solve hamed? : Unhandled Runtime Error TypeError: NetworkError when attempting to fetch resource. Source components/Dropzone.jsx (61:23) @ fetch 59 | 60 | const URL = process.env.NEXT_PUBLIC_CLOUDINARY_URL > 61 | const data = await fetch(URL, { | ^ 62 | method: 'POST', 63 | body: formData 64 | }).then(res => res.json())
i'm working on a project where users can purcase a mobile case before the order they have to edit the mobile back case , like they want (Adding the image , editing , rotating , resizing and adding the text) and once the editing is over they may save the image at that i have to store it in the backend using express , For the User interface im using the React , is there any NPM package to do that ??? I'm stuck in this for a week not able to figure it out.....
I am building an Ecom, at the admin side can I use React drop zone for the images and strings and also have one submit button to upload both the images and strings?
How can I get the actual File Type from in react-dropzone. Currently Type is extracted based on file extension however if I rename a file sample.pdf to sample.pdf.jpg, it will return type as Image/JPEG not as application/pdf.
Good question, you can pass a custom `validator` function that receives the `File` as the argument, do whatever validation you need to do and then decide whether or not the file is accepted or rejected.
@@hamedbahram Thanks Hamed. However when I try to add validator ' Object literal may only specify known properties, and 'validator' does not exist in type 'DropzoneOptions'.ts.
@@shyamksukumaran check the docs, you should be able to add a custom validator function. Here is a link: react-dropzone.js.org/#section-custom-validation
You need to use a unique `key` attribute for child elements inside of a list. Usually happens when you're using `map` to loop through an array of data to render a react element for each object.
@@hamedbahram Hi, thanks for the response. I have fixed that. My NEXT_PUBLIC_CLOUDINARY_URL didn't had /image/upload at the end of url. Without it, had CORS error message in console.
Hamed, huge thanks for the awesome tutorials! You didn't just whip up a useful component, but you also broke it down and threw in some great tips. Keep the cool stuff coming our way!
You're welcome Mario! Thanks for your comments man. I appreciate it.
This is honestly one of the greatest things on the internet.
You teach very well. Thanks so much, I was trying to do something exactly like this and couldn't find anything until this.
Thanks for your kind feedback, Ahren! I'm glad you found the video helpful.
@@hamedbahram For sure! Thanks for taking the time to create this video!
@@ahrenwagner2993 my pleasure!
very usefull content for me, I was looking for something like this.TNX a lot Hamed
Glad to hear that!
exactly what I was looking for, very helpful
Glad to hear!
huge thanks for the awesome tutorials!
My pleasure!
Thanks for amazing lesson! I have a question - I am unable to access the preview property in Files object in the JSX. The error that I am getting is "Property 'preview' does not exist on type 'File' " Have done the exact same approach that you have mentioned in the video. just that my project supports react typescript.
You'd have to manually add preview to each file using `URL.createObjectURL(file)`
@@hamedbahram I'll try this out.
@@mayank19saxena Or you could use a custom type for this. First define the custom type like this type UploadedFile = File & { preview: string }; and then, where you have the useState do something like this const [files, setFiles] = useState([]);
Thank you very much sir. This video saved my day.
Glad it helped.
What if we need to get all the urls for multiple images? Atm, we upload multiple images to cloudinary but only get back one url for a single image. Ideally, would like to have array of image urls which then can be sent to backend api to store in some DB. I've tried to store image urls via state after getting back data but when i access it, the state array is not yet populated with the urls.
You'd need to loop through your form files and upload them one by one to cloudinary, get the url, maybe push it to an array, and at the end write to your database.
@@hamedbahram
Yea I tried that but the issue is that it doesnt wait for the state array to be populated hence just empty array.
const handleSubmit = async (e) => {
e.preventDefault()
if (!files?.length) return
console.log('files:', files)
files.forEach(async (file) => {
const formData = new FormData()
formData.append('file', file)
formData.append('upload_preset', presetKey)
axios
.post(
`api.cloudinary.com/v1_1/${cloudName}/image/upload`,
formData
)
.then((res) => setImgUrls((prevVal) => [...prevVal, res.data]))
.catch((err) => console.error(err))
})
//does NOT WAIT until the loop is completely done above to populate the state array
console.log('Sending img url to my backend server...')
console.log('imgUrls', imgUrls)//[ ]
}
Hey man real thanks for this insightful video about react dropzone and cloudinary. I have a question can we upload multiple files at the same time using cloudinary
Yeah I think you'd have loop over your files and make multiple requests.
Excellent information
Glad it was helpful!
Hi, what if I wanted to save these files to a local database (i.e., a folder on my desktop) would that be possible? I wanted to use this to for an MVP I'm creating:
- Drag and drop files, save to local folder (mock database) using React Dropzone
- Run a python code that goes into that folder and executes code
Saving files locally won't really work once you deploy your app to serverless platforms like Vercel. You should use a real data base or a media cloud provider to store your files. You can look into this for file storage => www.bytescale.com
It doesn't show not-allowed cursor when dragging non-image. What can we do with that?
Not sure... Check the docs
Thank you, Hamed. Is there a way to set a minimum image width and height?
Not out of the box, but I guess you can implement it using a custom validator. Something like this:
```
function imageDimensionValidator(file) {
const image = new Image()
image.onload = function () {
console.log(this.width, this.height)
}
image.src = URL.createObjectURL(file)
}
```
Hi
could you say me the font name that you are using in your vs code please
Hey! I'm using Operator mono.
hey i wanted upload audio instead of images what major changes i have to make?
Not really, you can change the `accept` property.
After the Droping of pictures, how can i save them until the work finish, without a database pls
I'm not sure if I understand the question. Can you explain what you mean by saving the files until work is finish without a database? where do you want to save the files? In the video I save the files in my cloud storage (Cloudinary) and get a URL back which I can write to my database later.
Hi thanks for the tutorial! I am also using this method of having a separate state for the selected files so as to allow removal of files and selecting files one by one. However I have one issue - when I use the maxFiles property, this property is tied to the acceptedFiles from react-dropzone, which means that if my maxFiles = 3, and I select one by one, I can still end up selecting more than 3, because acceptedFiles "refreshes" each time we select a file. Do you have a solution for this? Thanks again!
You can pass a custom validator function where you can check the number of current files in your local state and throw an error if it exceeds your maximum number of files.
@@hamedbahram Thanks for the quick reply! Yes I did see that, but I am not able to access the number of files that the user is about to select. For example let's say max is 3. If the user already selected 2, and is now about to select another 2, that shouldn't be allowed, but if he is about to select 1 it should be allowed. However interestingly, I was able to set maxFiles dynamically like 3-files.Length (where files is my custom useState for the files). That worked like a charm!
@@wheeiraeth Sweet!
Unhandled Runtime Error
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
Im getting this error
Not sure where you're getting that! Compare your code to mine (link in the video description) and see what you're doing differently.
It seems i have fixed this issue, but another one popped,and trying to solve this with no result. any idea how to solve hamed?
: Unhandled Runtime Error
TypeError: NetworkError when attempting to fetch resource.
Source
components/Dropzone.jsx (61:23) @ fetch
59 |
60 | const URL = process.env.NEXT_PUBLIC_CLOUDINARY_URL
> 61 | const data = await fetch(URL, {
| ^
62 | method: 'POST',
63 | body: formData
64 | }).then(res => res.json())
@@santiago97399 Sorry it's hard to tell what's going wrong. Again compare your code to mine :)
how can i do this for google cloud services since its json?
You can use the Google cloud storage SDK and upload your files to your bucket.
For some reason it tells me "Unexpected end of input" at res.json, my syntax seems to be correct though
Not sure why that is Mike. You can pull down my code and compare it to yours.
i'm working on a project where users can purcase a mobile case before the order they have to edit the mobile back case , like they want (Adding the image , editing , rotating , resizing and adding the text) and once the editing is over they may save the image at that i have to store it in the backend using express , For the User interface im using the React , is there any NPM package to do that ??? I'm stuck in this for a week not able to figure it out.....
Is it for working with the image?
@@hamedbahram yes full and full image editing add mulpti in the particular layout editing there
I am building an Ecom, at the admin side can I use React drop zone for the images and strings and also have one submit button to upload both the images and strings?
What do you mean by strings?
@hamedbahram I mean a form input for "letters", "words". Like we have in boolean, strings, images, e.t.c.
How can I get the actual File Type from in react-dropzone. Currently Type is extracted based on file extension however if I rename a file sample.pdf to sample.pdf.jpg, it will return type as Image/JPEG not as application/pdf.
Good question, you can pass a custom `validator` function that receives the `File` as the argument, do whatever validation you need to do and then decide whether or not the file is accepted or rejected.
@@hamedbahram Thanks Hamed. However when I try to add validator ' Object literal may only specify known properties, and 'validator' does not exist in type 'DropzoneOptions'.ts.
@@shyamksukumaran check the docs, you should be able to add a custom validator function. Here is a link: react-dropzone.js.org/#section-custom-validation
Do we have progress bar option
That can be a nice feature. I don't have it in this tutorial though.
Excellent explanation, Thank you !
You are welcome! Glad it was helpful.
دمت گرم✌❤❤
Thanks Ali Jan.
Having an unsigned url is a security issue. Users can fill up your cloudinary very quickly with images.
That's right, Gabriel; using a signed preset for a production application is better. Appreciate your feedback.
@@hamedbahram can you tell how to achieve that?
@@SanchitTewari Watch this video where I explaing how to use signed uploads in Cloudinary: ruclips.net/video/gW7DSJ2a6pg/видео.html
@@hamedbahram i actually came up with an alternative...
we can just convert it into base64 right?
hi teacher Warning: Encountered two children with the same key. How can I fix this?
You need to use a unique `key` attribute for child elements inside of a list. Usually happens when you're using `map` to loop through an array of data to render a react element for each object.
Hi, anyone having cors issue?
I haven't had that on my end. What error are you getting?
@@hamedbahram Hi, thanks for the response.
I have fixed that. My NEXT_PUBLIC_CLOUDINARY_URL didn't had /image/upload at the end of url. Without it, had CORS error message in console.
@@noname-rp8pv Awesome!