Search code examples
javascriptvue.jselectronvuexelectron-builder

Record added in nedb is single but why VUE store same record multiple times?


I'm using electron with Vue. I'm saving data using nedb. I'm sending the event to background.js from vue component and when it returns with data it adds data in vuex in fibbonaccicaly. like

  • If I add 1 object let's say A then vuex store 1 object

  • if I add 1 more object let's say B then vuex store has total 3 objects (1 for A and 2 for B); and so on.

So I need to insert data in vuex only one time. How'd I do that ?

// In CreateNewTodo.vue

methods:{

// saveTodo method get triggers when user submit the form in modal

saveTodo() {
      if (this.isFormValid) {
        const newTodo = {
          task: this.task,
          priority: this.priority,
          eventDate: this.eventDate,
          createdDate: new Date(),
          completedDate: null,
          isCompleted: false,
        };

    // new Todo is an object that contains data that is requested from user 
    // from a form like task, priority and eventDate 

    ipcRenderer.send('createNewTodo', newTodo);
    ipcRenderer.on('createNewTodoResponse', (e, newDoc) => {
      if (typeof newDoc === 'object') {
        this.$store.dispatch('createNewTodo', newDoc);
        $('#createNewModal').modal('hide'); 
      } else {
        $('#createNewModal').modal('hide');
      }
    });
  }
},
}

// In background.js

ipcMain.on('createNewTodo', (e, args) => {

  // db.performTask is a function that insert document/record in nedb. 
  // I've used nedb-promises. In return we'll get promise.

  const dbpromise = db.performTask('todos', 'insert', args);

      // newDoc is the newly inserted document, including its _id

      dbpromise.then((newDoc) => {
        e.sender.send('createNewTodoResponse', newDoc);
      })
        .catch(() => {
          e.sender.send('createNewTodoResponse', 'error');
        });
    });

// vuex store

const state = {
  todos: [],
};

const getters = {
  getAllTodos(todosState) {
    return todosState.todos;
  },
};

const mutations = {
  CREATE_NEW_TODO(todosState, todo) {
    todosState.todos.push(todo);
  },
};

const actions = {
  createNewTodo({ commit }, todo) {
    commit('CREATE_NEW_TODO', todo);
  },
};

Solution

  • Each time you save a todo, you register a new listener for the IPC reply channel. The listeners all stay active and each picks and processes each event. That's not what you want, you want to process each response only once and electron has a method for that :) try this one:

        // register a listener to process the response (once)
        ipcRenderer.once('createNewTodoResponse', (e, newDoc) => {
          if (typeof newDoc === 'object') {
            this.$store.dispatch('createNewTodo', newDoc);
            $('#createNewModal').modal('hide'); 
          } else {
            $('#createNewModal').modal('hide');
          }
        });
    
        // send the request
        ipcRenderer.send('createNewTodo', newTodo);