Updating multiple values in succession fails
jloh opened this issue · comments
I have a dataview table like this that updates several values at once when I hit a button on it:
const {update} = this.app.plugins.plugins["metaedit"].api
const {DateTime} = luxon
const waitAmount = 100
const startButton = (bookPath) => {
const btn = this.container.createEl('a', {"text": "Start"});
const book = this.app.vault.getAbstractFileByPath(bookPath);
const startedDate = DateTime.now().toFormat('yyyy-MM-dd')
const lastRead = DateTime.now()
btn.addEventListener('click', async(evt) => {
evt.preventDefault();
await update('status', 'reading', book);
await update('started', `[[${startedDate}]]`, book);
await update('lastRead', lastRead, book);
await update('updated', lastRead, book);
});
return btn;
}
dv.table(["Title", "Author", "Added", ""], dv.pages("#book")
.where(b => b.file.path != "System/Templates/Book.md")
.where(b => b.status == "backlog")
.sort(b => b.file.name.replace(/(a|the)\s/gmi, ""), 'asc')
.map(b => [
dv.fileLink(b.file.path, false, b.title),
b.author,
dv.date(b.created).setLocale('en-au').toFormat('DD'),
startButton(b.file.path)
])
)
My problem is I also have Obsidian Sync enabled which seems to clobber some of the updates. Some devices update all the values successfully, others only update the first two before I'm guessing Sync kicks in which seems to undo/prevent the final two updating.
I've successfully worked around this by adding some sleep's in between the updates so it looks like this:
const {update} = this.app.plugins.plugins["metaedit"].api
const {DateTime} = luxon
const waitAmount = 100
const startButton = (bookPath) => {
const btn = this.container.createEl('a', {"text": "Start"});
const book = this.app.vault.getAbstractFileByPath(bookPath);
const startedDate = DateTime.now().toFormat('yyyy-MM-dd')
const lastRead = DateTime.now()
btn.addEventListener('click', async(evt) => {
evt.preventDefault();
await update('status', 'reading', book);
await new Promise(r => setTimeout(r, waitAmount));
await update('started', `[[${startedDate}]]`, book);
await new Promise(r => setTimeout(r, waitAmount));
await update('lastRead', lastRead, book);
await new Promise(r => setTimeout(r, waitAmount));
await update('updated', lastRead, book);
});
return btn;
}
dv.table(["Title", "Author", "Added", ""], dv.pages("#book")
.where(b => b.file.path != "System/Templates/Book.md")
.where(b => b.status == "backlog")
.sort(b => b.file.name.replace(/(a|the)\s/gmi, ""), 'asc')
.map(b => [
dv.fileLink(b.file.path, false, b.title),
b.author,
dv.date(b.created).setLocale('en-au').toFormat('DD'),
startButton(b.file.path)
])
)
This seems to make it consistently update all the values as I'm guessing it gives Sync enough time to do whatever it is doing to the file. I know its Sync breaking the update because when I disable the plugin the button works completely fine updating all values as intended.
Is there a better work around or way to just update the values all at once so its just one file change?
Thanks in advance and thanks for the plugin!
I'm also doing this and I just found your post, I don't have obsidian sync and I'm getting the same behaviour. I can only update two values at a time, in succession. Did you find a solution?
Even without sync activated, this just not works reliably with promise chaining. I would appreciate it if there was a function that updates several values at once. 👍
Yea, I'm having the same problem and got it working for now also by just making it sleep for a 100ms between each update. But it would be nice to have a less clunky solution in the future. 👍