I'm creating an Electron app where the user creates and works on a "project." I'm trying to implement a "Save" button so the user can save their progress. I think there are two steps to this functionality: (i) get the file name/location from the user and then (ii) save the data to file.
For step (i) I have implemented
const get_file_name = async () => {
try {
return await window.showSaveFilePicker({
types: [{
accept: { "application/octet-stream": [".custom"], }
}],
});
// catches when the user hits cancel
} catch(err) {}
}
}
}
However, I get the message dyn.age80g55r is not a valid allowedFileType because it doesn't conform to UTTypeItem because I use custom as my file extension. Is there a way to use a custom file extension? I would like it to be specific to the app that I am creating.
For step (ii) I implemented:
get_file_name().then((file) => {
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.downlaod = file.name;
link.href = url;
link.click();
});
However, this just opens a new page showing the contents of blob rather than downloading the new file. Does anyone know how I can download blob into the file?
More generally, is there a better way to allow the user to save their progress to file?
Your current approach is based on the mindset on implementation within the render side / process only.
Electron has a multi-process architecture. Read about the Process Model for more information.
Utilising this multi-process model, we can move the file dialog selection window and the download (referred to in the below code as the save function) to the main process.
If you have the ability to, keep your render process(es) as simple as possible. Use them only for rendering the UI and UI interaction. IE: No heavy lifting.
The minimum reproducible example below does the following:
textareafield for entering example data.Savebutton to save the example data to the selected file extension (.txtfile in this case).You mentioned that you also wish to use a custom file extension. The below code demonstrates its use. You can change your "custom" file extension to anything you wish, even a non-standard file extension that only your application will recognise and understand.
Whilst your requirements may be very different to the example code below, such as:
.jsondata to a file instead of plain text.Savebutton.All going well, this should be easy enough for you to implement as only you know the requirements of your application.
main.js(main process)preload.js(main process)And how to use it...
index.htm(render process)