0

I have a simple shopping app that I made with react, react-router and bootstrap. I've got a form on a certain page where I can add a new product to the database.

There I can provide a name, description, category, and upload a product image.

The thing is when I upload an image through <input ="file">, I want to somehow get the absolute path of the image when I press open and store it inside the local state.

Till now my code is like this...

function Form() {
  const [imageUrl, setImageUrl] = useState("");

  // ... a bunch of code here

  return (
    <form style={styles.form}>

      // ... a bunch of code here

      <div className="form-group">
        <label htmlFor="image" className="form-label" style={styles.label}>
          Picture
        </label>
        <input className="form-control" type="file" id="image" required />
      </div>

      // ... a bunch of code here

    </form>
  )
}

I've tried this but that is for Jquery.

I'm new to React, so please be kind, and thanks in advance :)

  • Did you even read the answers in the question you linked? First, there is an answer without any jQuery (for Firefox). Second it clearly states that it is not possible. – cloned May 06 '21 at 07:47
  • Like many other have already stated, you can't get the path, the best you can get is a fileHandle references that you can store and reuse if you use the new native file system access api (mostly just avalible in chrome atm) – Endless May 10 '21 at 12:56

2 Answers2

0

You can't get the full path due to security reasons. You can try fs-js module to work with files https://www.npmjs.com/package/fs-js

charmful0x
  • 145
  • 8
0

Short answer; you can't.

The input file element will deliberately hide the full path for security reasons:

The string is prefixed with C:\fakepath, to prevent malicious software from guessing the user's file structure. (https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file)

In general, when you use the file input, it's to upload the file; you shouldn't need the path at all.

Edit for example upload to Google Drive

NOTE: this requires you to be authenticated

Assume you have your html like so:

<form id="load-image-form">
    <input type="file" id="chosen-image" accept=".jpg,.png">
    <button type="submit">Upload</button>
</form>

Then your script to upload the file would look like this:

const fileInput = document.getElementById('chosen-image')
document.getElementById('load-image-form').addEventListener('submit', e => {
    e.preventDefault();

    // check if there's any actual files chosen
    if (fileInput.files.length == 0) {
        console.log(`No files chosen`);
        return;
    }

    // assume only one file - read it, and when it's ready, upload to google drive
    const file = fileInput.files[0];
    const reader = new FileReader();
    reader.onload = () => {
        console.log(`File loaded locally - uploading`)
        fetch('https://www.googleapis.com/upload/drive/v3/files?uploadType=media', {
            method: 'POST',
            headers: {
                'Content-Type': file.type,
                'Content-Length': file.size
            },
            body: reader.result
        })
        .then(data => data.json())
        .then(console.log)
        .catch(console.error)
    }
    reader.readAsArrayBuffer(file);
})

Basically once the form is submitted, check if there's a file selected, if so load it using FileReader, then POST it to Google Drive

When I test this locally, I get an Authorization Login Required error, so you need to be logged in for this.

To upload it to your server (e.g. Node), use the link I posted in my comment: https://stackoverflow.com/a/15773267/639441

divillysausages
  • 7,649
  • 3
  • 20
  • 37
  • Thanks, I just wanted the complete path so that I could upload the image with google drive API. Any other way to do that? –  May 06 '21 at 08:11
  • Looking quickly at https://developers.google.com/drive/api/v3/manage-uploads#simple, you have the step `"Add the file's data to the request body."`, so it doesn't look like you need the path at all. The return from the `` should give you the file data – divillysausages May 06 '21 at 08:17
  • Actually, I needed the file path so that I could make an API call to my server and pass that in the body of the request. Then the server could read the contents of the file using the absolute path with node's `fs` core module and create a stream and upload that to google drive. –  May 06 '21 at 09:20
  • Is there a way to get the `file data` on the client-side? Please help. –  May 06 '21 at 09:20
  • Your server will absolutely not be able to read the stream of a user's computer. Node's `fs` module will only work on the drive of the server. The only way it'll have access to the user's computer is if the user is running the server locally. – divillysausages May 06 '21 at 09:26
  • So can we get the file data into a sort of stream on the client-side? –  May 06 '21 at 09:27
  • If not can you suggest any other easy way to upload an image? –  May 06 '21 at 09:29
  • You can either load the file directly into Google Drive using their APIs, or upload the file to your server and do the same - that's literally what the `` element is for. – divillysausages May 06 '21 at 09:30
  • There's already questions on uploading files with node + forms etc - https://stackoverflow.com/a/15773267/639441 is probably what you're looking for – divillysausages May 06 '21 at 09:31
  • The example on the Google Drive API also uses forms to directly upload a file – divillysausages May 06 '21 at 09:31
  • Please can you post a complete answer for this? –  May 06 '21 at 09:36
  • I've added an edit. This assumes that you've handled the necessary login steps for actually adding things to Google Drive – divillysausages May 06 '21 at 10:27
  • 1
    the way you use FileReader to upload a file in your example is unnecessary use of RAM, You can ditch the FileReader all together and just use the file as body `{method: 'POST', body: file}` – Endless May 10 '21 at 13:00