5

Well, I'm working on a certain app that would improve work in the company. For this I would need to create, save and read a file without a dialog box.

I created this code with the help of documentation and the Internet:

const electron = require('electron');
let fs = require('fs'), app = electron.remote;
let localData, fileName = "appdata.json";

function loadAppData() {
    fs.readFile(fileName, (err, data) => {
        if (err) {
            console.log("There was a problem reading the data!");
            // console.log(err);
        } else {
            console.log("Data loaded!");

            localData = JSON.parse(data);
            console.log(localData);
        }
    });
}

function saveAppData(content) {
    content = JSON.stringify(content);

    fs.writeFile(fileName, content, (err) => {
        if (err) {
            console.log("There was a problem saving data!");
            // console.log(err);
        } else {
            console.log(Data saved correctly!");
            loadAppData();
        }
    });
}

function initappData() {
    if (fs.existsSync(fileName)) {
        console.log("File detected, loading");
        loadAppData();

    } else {
        let defData = {
            "patients": [],
            "actions": [],
            "visits": []
        };
        console.log("No file! I create! Saving! Loading!");
        saveAppData(defData);
    }
}
initappData();

And I have a problem because if the script works on the local version, after the application build on MacOS (using electron-builder) the error appears in the console: "There was a problem writing data!". After displaying the error content appears: Error: EROFS: read-only file system, open 'appdata.json'.

I checked permissions, I checked in other locations - still the same :( I was looking for a solution on the net but unfortunately nothing solved the problem.

Has anyone encountered such a problem?

Mativve
  • 63
  • 2
  • 4

1 Answers1

4

After the build. The resource will be packaged inside asar file But this is just read-only. You can't modify the file inside of asar.

If I were you. I'm going to store the appData.json at Application Support. And I think this is the popular configure for application.

You can get the Application Data path by using this.

function getAppDataPath() {
  switch (process.platform) {
    case "darwin": {
      return path.join(process.env.HOME, "Library", "Application Support", "Your app name");
    }
    case "win32": {
      return path.join(process.env.APPDATA, "Your app name");
    }
    case "linux": {
      return path.join(process.env.HOME, ".Your app name");
    }
    default: {
      console.log("Unsupported platform!");
      process.exit(1);
    }
  }
}


function saveAppData(content) {
    const appDatatDirPath = getAppDataPath();
    
    // Create appDataDir if not exist
    if (!fs.existsSync(appDatatDirPath)) {
        fs.mkdirSync(appDatatDirPath);
    }

    const appDataFilePath = path.join(appDatatDirPath, 'appData.json');
    content = JSON.stringify(content);

    fs.writeFile(appDataFilePath, content, (err) => {
        if (err) {
            console.log("There was a problem saving data!");
            // console.log(err);
        } else {
            console.log("Data saved correctly!");
            loadAppData();
        }
    });
}
tpikachu
  • 3,339
  • 2
  • 12
  • 34
  • Hi! Thanks for response. I want to ask, where I should use this code? In main running script and use it with ipcRenderer in index file or in index.html link script like normal HTML script? – Mativve Mar 31 '20 at 12:13
  • You can use this anywhere. To use this code at your renderer then you should sure if the nodeIntegration is enabled when you are creating your browserWindow. But I'd recommend you to do this operation at your main. Of course, you can use ipc API if needs. – tpikachu Mar 31 '20 at 12:20
  • Thanks for advice :) So I put modified my and your code into index.html: https://gist.github.com/Mativve/6f33cd280e3387891e0d9cc3576b8488 In index.js (main file of electron) I have: https://gist.github.com/Mativve/2a5834a0eba6c43cfbf29afee24e5e0d Unfortunately after build my app in console an error appears: `Uncaught ReferenceError: path is not defined at getAppDataPath (index.html:19) at saveAppData (index.html:50) [...]` I tried find solution of 'path' variable or global variable but I found nothing interesting and solving my problem :/ – Mativve Apr 01 '20 at 05:46
  • You are not inclucing the ```const path = require('path')``` – tpikachu Apr 01 '20 at 12:16
  • Oh, I forgot about that. Thank you very much for your help ;) Now It's work correctly! – Mativve Apr 02 '20 at 07:36
  • Hi Mativve, I'm having a similar issue to yourself with my Electron app. When my application is being installed with a .zip file on my MAC it is not creating the application directory in the Application Support folder. Is this something you set in the package.json? Thanks for your help. – OrangeSubmarine121 Jun 03 '20 at 15:52
  • 1
    @OrangeSubmarine121 Sorry for my long response. Here is the code with package.json, index.js and index.html -> https://gist.github.com/Mativve/b77098ce42e6947ea35ae6e1d6a28186 I hope that helps you ;) – Mativve Oct 01 '20 at 08:11