0

I think I know that this is a 'no' but I'm going to ask anyway:

I have an SPA (react) and the user sends in items to be repaired. I'm trying to get it so that the user can take a picture of their item for identification.

I'm hoping to create a collection of data to manipulate throughout the app, like so:

const repairs = [
  {name: 'item1', imgURL: '<reference to local file in some way>'},
  {name: 'item2', imgURL: '<reference to other local file in some way>'}
];

To get the data I'm going to use a form (obviously!). In effect the form where the user inputs the data should use a file upload, right?! And be something like this:

<form id="myForm">
    <input type="file" name="avatar" id="avatar">
    <input type="text" name="name" id="name">
    <input type="submit">
</form>

Using the FormData API, I can get a reference to the file and show it on that page. The problem really is about persisting that reference.

On another page I may want a list of repair items, like so:

<li className="repair">
  <img src={repair.imgURL} alt={repair.name} />
</li>

but the question is how to persist and reference the file path...

EDIT: Sorry, to be clearer, I know about localstorage. My issue was getting the reference to the file. When you get the FormData object, the file data looks like this:

File {
  name: "BB_map_pin_black.png",
  lastModified: 1491366453000,
  lastModifiedDate: Wed Apr 05 2017 05:27:33 GMT+0100 (BST), 
  webkitRelativePath: "", size: 1516…
}

...which isn't enough to reference it by on another page. I need a file path or for the system to hold some kind of reference to the location of that file because the file listed in the object above is in my downloads folder, not the folder my project is currently in...

user1775718
  • 1,499
  • 2
  • 19
  • 32

2 Answers2

1

You may want to look into localStorage to store the filePath

The localStorage property allows you to access a local Storage object. localStorage is similar to sessionStorage. The only difference is that, while data stored in localStorage has no expiration time, data stored in sessionStorage gets cleared when the browsing session ends—that is, when the browser is closed.

Store path

localStorage.setItem('filePath', 'YOUR_PATH');

Read Path

var file_path = localStorage.getItem('YOUR_PATH');

You can also store objects by stringifying it.

localStorage.setItem('formData', JSON.stringify(YOUR_FORM_DATA_OBJ));

when reading parse to object

var YOUR_FORM_DATA_OBJ = JSON.parse(localStorage.getItem('formData'));

UPDATE

Checkout this fiddle

Your cannot read path to the file due to security issue

but you can convert your file to blob dataURL and save it in localStrorage

In the fiddle above I have used image to store in localstorage and show them later.

STORING FILE

avatar = input.files[0];    //Read your input file here
var reader  = new FileReader();   //create a FileReader Object 

reader.addEventListener("load", function () { // A listener to read the file as blob
  var data = reader.result; // Your blob data

  // Saving the blob data to localStorage
  localStorage.setItem('fileData', // Key and object storing name and blob data of file
                        JSON.stringify({name:avatar.name,data:data})); 
  }, false);

  if (avatar) {
    // reading file to get blob, this will call the load method above
    reader.readAsDataURL(avatar);
  }

READING FILE

var fileData = localStorage.getItem('fileData');  // getting data from local storage

   if(fileData) {
    fileData = JSON.parse(fileData);      // parsing local storage data
    avatar=dataURLtoFile(fileData.data,"filename"); //converting dataURL to file

}

/*Function to convert blob dataURL and returns a file object
  Takes a dataURL (data:image/png;base64,sadasd...) and filename
  and returns a file object
*/
function dataURLtoFile(dataurl, filename) {
    var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new File([u8arr], filename, {type:mime});
}

FULL JS

window.input = $('#myForm').find('#avatar')[0];
window.preview = $('#show');
window.avatar;

function dataURLtoFile(dataurl, filename) {
    var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new File([u8arr], filename, {type:mime});
}

function changeFile() {

  avatar = input.files[0];    //Read your input file here
  var reader  = new FileReader();   //create a FileReader Object

  var path = URL.createObjectURL(avatar); //Create URL to show current image
  preview[0].src=path;  // set url of blob to image src (just to preview current image)

  reader.addEventListener("load", function () { // A listener to read the file as blob

  var data = reader.result; // Your blob data

  // Saving the blob data to localStorage
  localStorage.setItem('fileData', // Key to store
                        JSON.stringify({name:avatar.name,data:data})); // an object storing name and blob data of file
  }, false);

  if (avatar) {
    reader.readAsDataURL(avatar);  // reading file to get blob, this will call the load method above
  }

}

input.addEventListener('change', changeFile); // adding change listener to input 

window.init = function(){ // called on page load

   var fileData = localStorage.getItem('fileData');  // getting data from local storage

   if(fileData) {
    fileData = JSON.parse(fileData);      // parsing local storage data
    avatar=dataURLtoFile(fileData.data,"filename"); converting dataURL to file
    var path = URL.createObjectURL(avatar);// getting a url to show the image
    preview[0].src=path; // setting url to image
   }


}

init();
Nadir Laskar
  • 4,012
  • 2
  • 16
  • 33
  • There could be a problem about this. "Another page" could be an another domain. You can use the data in the localStorage only in the domain in which you saved the files. – Matthias Gwiozda Jun 09 '17 at 10:30
  • Yes, it is domain specific storage of data. For cross domain you have to use message passing and iframe here is more information on that https://stackoverflow.com/questions/33957477/cross-domain-localstorage-with-javascript – Nadir Laskar Jun 09 '17 at 10:39
  • @NadirLaskar: Thanks Nadir. I need to be clearer and I've edited the question above. The method of persisitence (localstorage) is easy, it's getting the path for the file that's difficult because it only seems to store its name. – user1775718 Jun 09 '17 at 10:46
  • @user1775718 I have added a fiddle checkout the updated answer – Nadir Laskar Jun 09 '17 at 13:05
1

Files don't have a JS-accessible path property because that can reveal usernames and other confidential/personal information to the site's operators. Also, once you reload a page, you've lost the file reference; it won't help to have the full path because you still won't have a reference to the File object, and you can't pre-populate an <input type=file>. You can save the contents of the file, and the name, but not the path. If you upload the file to your server, you can have your server return a url that can be linked from any page.

dandavis
  • 16,370
  • 5
  • 40
  • 36