Emm
Emm

Reputation: 2507

Upload and preview a picture using FileReader API

Struggling to implement the logic to enable a user to upload a picture and preview the picture before sending it to the server. So basically upload a profile pic and preview it before saving it. Have been trying to use the FileReader API to facilitate this. Here is my code:

const [fileDataURL, setFileDataURL] = useState(null);
const [profilePic, setProfilePic] = useState(null);
...
        useEffect(() => {
          let fileReader, isCancel = false;
          if(profilePic){
            fileReader = new FileReader();
            fileReader.onload = (e) => {
              const { result } = e.target;
              console.log('what is result', isCancel)
              if(result && isCancel){
                setFileDataURL(result)
                console.log('fileDataURL updated', fileDataURL)
              }
            }
            fileReader.readAsDataURL(profilePic)
        }
        return () => {
          isCancel = true;
          if(fileReader && fileReader.readyState === 1){
            fileReader.abort();
          }
        }
      }, [profilePic]);
        function onImageChange(e) {
          const image = e.target.files[0]
          console.log('image', image)
          setProfilePic(image)
          console.log('in state', profilePic) 
        }
...
        return (
...
                <Row>
                  <Col md="4">
                    <Card className="card-user">
                      <div className="image">
                        <img src={fileDataURL} alt="preview"/>
                      </div>
                      <CardBody>
                    <input type="file"
                            onChange={ e => onImageChange(e) }
                            accept= "image/*"
                            />
                        <div className="author">
                          <a href="#pablo" onClick={(e) => e.preventDefault()}>
                            <label htmlFor="photo-upload" className="custom-file-upload fas">
                                <div className="img-wrap img-upload">
                                    <img
                                        alt="..."
                                        className="avatar border-gray"
                                        src={fileDataURL}
                                    />
                                </div>

I'm not seeing any errors to indicate what might be going wrong. I select a picture, I can console.log details regarding the picture but cannot preview said picture.

I do know that when I try to console log fileDataURL after setting it to state is that I get a null value. I assume this has more to do with that setting to state is asynchronous. The image is supposed to be in fileDataURL

Upvotes: 0

Views: 596

Answers (1)

Mina
Mina

Reputation: 17009

If you just want to preview the image, you can use URL.createObjectURL(file), to get the URL string representation of the file.

useEffect(() => {
        if(profilePic){
          setFileDataURL(URL.createObjectURL(profilePic))
        }
      }, [profilePic]);

Upvotes: 2

Related Questions