1

I am creating a multipart form in React. Everything is working fine except for file input field.

Below is the code, what I am trying to do.


                 <div className="col-lg-6 col-md-12">
                    <form encType="multipart/form-data" onSubmit={this.onSubmit}>
                     <div className="form-group">
                        <div className="custom-file mb-3">
                          <input
                            type="file"
                            className="custom-file-input"
                            id="gerberFile"
                            onChange={this.handleFileChange}
                          />
                          <label className="custom-file-label">
                            {gerberFileLabel}
                          </label>
                        </div>
                        {errors.gerberFile && (
                          <div className="alert alert-danger">
                            {errors.gerberFile}
                          </div>
                        )}
                      </div>
                    </div>
                  </div>

       handleFileChange = e => {
        const file = e.target.files[0];
        if (!(file.name.includes(".zip") || file.name.includes(".rar"))) {
          const errors = { ...this.state.errors };
          errors.gerberFile = "Gerberfiles are only allowed in .zip or .rar";
          this.setState({ errors });
        } else {
          console.log(`file ? ${JSON.stringify(file)}`);

          const formFields = { ...this.state.formFields };
          formFields.gerberFile = file;
          this.setState({ formFields });
          this.setState({ gerberFileLabel: file.name });
        }
      } 

The strange part is I am able to console.log file name and use it as lable place holder. However, whenever I try to console.log File object I get an empty {} object.

What exactly I am doing wrong here? I went through multiple tutorials everyone seems to be doing the same thing and honestly i couldn't find it on SO.

I'd appreciate it greatly if anyone could help me.

5
  • What happens if you add a name="file" property to your file input? Commented Apr 17, 2020 at 13:55
  • I think you have a similar case as this one here: stackoverflow.com/questions/60544186/… You are trying to save something in the state in an async way, and when you do this, JavaScript has already nullified the data for the event parameter. Commented Apr 17, 2020 at 14:02
  • @TheDarkIn1978 nothing, I even tried to give very similar name as my id to name no affect has been observed. Commented Apr 17, 2020 at 14:31
  • @Enchew I can see your comment there to some extent it does make sense but how about this onChange={e =>console.log( file: ${JSON.stringify(e.target.files[0])})} it is still logging an emtpy object Commented Apr 17, 2020 at 14:39
  • Btw this was the closest I found in my context and @Enchew very similar to your answer: stackoverflow.com/questions/47442839/… However, my problem is a bit different than this. Commented Apr 17, 2020 at 14:44

1 Answer 1

1

Hi I am not sure what you try to achieve and what you mean by "try to read file"?

The File interface provides information about files and allows JavaScript in a web page to access their content.

A File object is a specific kind of a Blob, and can be used in any context that a Blob can. In particular, FileReader, URL.createObjectURL(), createImageBitmap(), and XMLHttpRequest.send() accept both Blobs and Files.

So you can store this in state and get back.

But if you need read file content you need to use FileApi. Look at this example component.

There are two handlers one is reading file onChange and second onSubmit event.

To test this component select some text file.

const FileComp = () =>{
  const fileRef = React.useRef<HTMLInputElement>(null)

  const onSubmit = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    const file = fileRef?.current?.files?.[0];

    if(file) {
      const reader = new FileReader();
      reader.onload = (e) =>{
        const res = e.target?.result;
        alert("Handle by onSubmit"+ res);
      };

      reader.readAsBinaryString(file);
    }
  }

  const onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = fileRef?.current?.files?.[0];

    if(file) {
      const reader = new FileReader();
      reader.onload = (e) =>{
        const res = e.target?.result;
        alert("Handle by onChange"+ res);
      };

      reader.readAsBinaryString(file);
    }
  }

  return <div>
    <form onSubmit={onSubmit}>
      <input type="file" id="myFile" ref={fileRef} onChange={onChange}></input>
      <button type="submit">Submit</button>
    </form>
  </div>
}

Hope this will help. Sorry for Typescript.

Sign up to request clarification or add additional context in comments.

2 Comments

Sorry my bad I should write when I try to log File object I am only getting an empty object (I am editing this now). My question has nothing to do with rendering stuff, consider it as a profile form where you asks bunch of personal questions and users picture.
Check what File is ... this just proxy to system. You can get name but nothing elsr i guess.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.