0

I'm building a tasks-to-do application using electron. As I'm new using it, I have found a lot of problems to make the tasks already uploaded persistent in the application.

I'm creating the tasks through a form completed by the user. This creates the task using dynamic HTML.

(Div form showed below)

<div class="div_GEN_form" id='div_GEN_form'>
        <div class="form_content" id="form_content">
            <div class="class_form_title">
                <span class="class_title_content_form">Add your task</span>
            </div>

            <form id='GEN_form' name='GEN_form' class="form"></form>
            <br><br>

            <input type="image" src="./icons/BACK.png" alt="Back" class="BACK_img" onclick="DOM_class.CloseFormDiv();">
            <input type="image" src="./icons/ADD.png" alt="Submit" class="ADD_img" id="submit_button">
        </div>
    </div>

The real problem is that I cannot find a solution to make the tasks already added permanent, since when I close the application, every task dissapears. This is the way I'm trying:

static AddDataToTable(typeImageSrc, date, name, comments) {
        const table = document.getElementById('id_data_table');

        const tasks = JSON.parse(localStorage.getItem('tasks')) || [];
        const taskExists = tasks.some(task => task.date === date && task.name === name && task.comments === comments);

        if (!taskExists) {
            const newRow = document.createElement('div');
            newRow.className = 'data_row';

            newRow.innerHTML = `
                <div class="data_cell"><img src="${typeImageSrc}" class="table_image"></div>
                <div class="data_cell">${date}</div>
                <div class="data_cell">${name}</div>
                <div class="data_cell">${comments}</div>
                <div class="data_cell"><img src="./icons/delete.png" class="delete_button" onclick="form.DeleteTask(this)"></div>
            `;

            table.appendChild(newRow);

            tasks.push({ typeImageSrc, date, name, comments });
            localStorage.setItem('tasks', JSON.stringify(tasks));
        }
    }

    static DeleteTask(button) {
        const row = button.closest('.data_row');
        const cells = row.querySelectorAll('.data_cell');
        const date = cells[1].innerText;
        const name = cells[2].innerText;
        const comments = cells[3].innerText;

        const tasks = JSON.parse(localStorage.getItem('tasks')) || [];
        const filteredTasks = tasks.filter(task => !(task.date === date && task.name === name && task.comments === comments));

        localStorage.setItem('tasks', JSON.stringify(filteredTasks));
        row.remove();
    }

    static LoadDataFromStorage() {
        const tasks = JSON.parse(localStorage.getItem('tasks')) || [];
        tasks.forEach(task => {
            this.AddDataToTable(task.typeImageSrc, task.date, task.name, task.comments);
        });
    }
}

module.exports = form;
form.LoadDataFromStorage();

I have also a main.js where I tried to configure the settings:

const { app, BrowserWindow } = require('electron');
const path = require('path');

function createWindow() {
    const mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            preload: path.join(__dirname, 'preload.js'),
            contextIsolation: false,
            enableRemoteModule: true,
            nodeIntegration: true
        }
    });

    mainWindow.loadFile('index.html');

    mainWindow.webContents.on('did-finish-load', () => {
        // No need to add an event listener here since it's done in the HTML
    });
}

app.on('ready', createWindow);

app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        app.quit();
    }
});

app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
        createWindow();
    }
});

I know that I can use electron storage module, but I don't know what to do.

Thank you

2 Answers 2

1

Since you’re using Electron then you should have access to node.js, which in turn gives you full access to the user’s hard disk!

So what on Earth are you doing wasting your time with local storage?

Leave that for websites! You are a desktop web-app remember? :)

So just create a config file (txt) of all your tasks in your program’s directory, which you should be able to find the next day, and the next... to open and process each time.

Here's a quick guide to basic disk access in node.js:

var fs=require('fs'); // declare the relevant node.js library


fs.writeFileSync(Path,S,'utf8'); // create a new file and write string "S" to it


let S=fs.readFileSync(Path,'utf8');  // Read a file's contents and assign to variable "S".


fs.unlinkSync(Path); // Delete a file


if(fs.existsSync(Path)){}  // Does a file exist?

NB: Error checking for each can be done with try{} catch(e){}

Research further here...

https://nodejs.org/docs/latest/api/fs.html

Tip: Stick to the synchronous versions of functions.

1
  • In the production env , it not good approach to use node Integration handling the data in a local storage is fine in longer run. other wise it lead to security vulnerabilities Commented Jun 12 at 5:15
0

If you are ok with nodeIntegration: ture look after content security policy.

There is a package called electron-store

 mainWindow.webContents.on('did-finish-load', () => {
        // Send the stored tasks to the renderer process after the window has loaded
        const tasks = store.get('tasks', []);
        mainWindow.webContents.send('load-tasks', tasks);
    });

then from this forward update renderer as you like and modify your handling functions based on your requirement.

If you consider about security.

update your main.js to

webPreferences: {
  preload: path.join(__dirname, 'preload.js'),
  contextIsolation: true,
  nodeIntegration: false,
  backgroundThrottling: false
}

you can use same package but need to create preload.js with contextBridge.exposeInMainWorld and your main.js you have to use ipcMain.on with get,save,delete functions

1
  • I made that and with some little changes in the code it worked perfect. Thanks mate
    – MavapeGZ
    Commented Jun 19 at 15:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.