This question is a little long-winded but I want you to understand exactly what is occuring...
I'm building a task manager desktop app (Electron) for our company to use and I have a strange behavior occuring. The task manager is 6 columns (one for each employee) and contains a vertical list of tasks to be completed. It includes a drag and drop feature so you can sort the tasks.
I'm using Dragula to handle the drag and drop portion, then collect the ID number of all of the tasks, in order from top to bottom, storing them in an array.
I'm using PouchDB to update the database and sync the other running applications.
For the Dragula / PouchDB side I am using the following code:
var containers = [];
containers.push(ReactDOM.findDOMNode(this.refs.taskContainer));
var drake = Dragula(containers);
drake.on('drop', function(el, target, source, sibling) {
// Get Desired Order of IDs
for(i = 0; i < source.children.length; i++) {
ids.push(source.children[i].id);
}
// Loop through IDs, write an "order" to tasks in PouchDB Database ("TaskData").
// TaskData's replication is "live" so it automatically syncs to the DB.
for(i = 0; i < ids.length; i++) {
TaskData.get(ids[i]).then(function(doc) {
doc.order = ids.indexOf(doc._id);
TaskData.put(doc).catch(function(err) {
console.log(err);
});
});
}
});
At this point, my TaskData now has a new "order" key, with the desired values. Now, I need to render the ReactJS Components -- in order.
Get tasks from props (refreshed from TaskData) and filter out what is needed:
var tasks = this.props.tasks.filter(function(task) {
if(task.archive !== 1) {
return true
}
});
I then sort the tasks by the above mentioned order number (using lodash.js) and map the sorted data to React Components:
tasks = _.sortBy(tasks, 'order').map(function(task) {
return <Task key={task.id} order={task.order} ...more props />
});
Great, my tasks are rendered in order and everything is looking good.
Now, the problem...
When I drag and drop to re-order my tasks from ["1", "2", "3", "4"]
to ["4", "1", "2", "3"]
, I actually get ["3", "4", "1", "2"]
. The tasks move and update (because of the Dragula / PouchDB code above). Weird... I type in the Dev Tools location.reload()
and to my suprise, the tasks are now ordered as I initially wanted: ["4", "1", "2", "3"]
.
Trying again, I move the tasks from ["1", "2", "3", "4"]
to ["1", "3", "2", "4"]
, the tasks reset back to ["1", "2", "3", "4"]
. Again, location.reload()
and the tasks are now ordered: ["1", "3", "2", "4"]
.
In trying to debug this, I found that if I disable the _.sortBy
function, the tasks stay put after being dropped (although they are out of order to begin with). The tasks move to their desired location and have the desired order number.
I've also found that if I disable the PouchDB .put()
, and keep the _.sortBy
working, it also works, but the data is not written to the server, and the order number does not update as a result.
Perhaps I have just been staring at the code for too long, but I cannot figure out why the tasks are bouncing around. Anyone have any ideas?
Thanks for your help!