Why I need to wait a random amount of time after creating a file with teplater?

I’m using templater to build a script that creates a subtopic from the current note.
It basically reads all the info from the current note, then creates a new note in the same folder as the “parent” with the parent name as prefix. Then, in case the template used to create the new note had any tag, the script concatenates the tags from the new file with the ones from the parent.
After struggling a lot with my approach where the last step was not working as expected I added some random delay before modifying the recently created file, and bum, it worked.

Some time ago I read the source code of templater, and I remember they were also introducing some random delay (which is a dirty but understandable practice):

Could be because of that?

Here is the code of my script:

const metadataMenu = app.plugins.plugins["metadata-menu"].api;
module.exports = async function (tp) {
    if (!tp.config.active_file) {
        new tp.obsidian.Notice('This template must be executed from an file to act as a parent.')
        return;
    }
    let parent_title = tp.file.title
    const parent_path = tp.config.active_file.parent;
    let subtopic = await tp.system.prompt("Subtopic");
    const file_name = `${tp.user.sanitize(parent_title)}-${tp.user.sanitize(subtopic)}`
    console.log(file_name);
    const templates = app.vault.getFiles().filter(f => f.path.startsWith('templates'));
    const template = await tp.system.suggester(t => t.basename, templates);
    console.log(template, file_name, parent_path);
    const newFile = await tp.file.create_new(template, file_name, true, parent_path);
    // Get the tags from the newly ceated file, in case the template had them
    const fileMetadata = await app.metadataCache.getFileCache(newFile);
    // Concat the tags from the parent with the tags from the new file/template
    const newTags = tp.frontmatter.tags.concat(fileMetadata.frontmatter.tags);
    console.info({ newTags, newFile })
    await sleep(300)
    // use the metadata-menu plugin to set the tags on the new file
    await metadataMenu.postValues(newFile, [{ name: 'tags', payload: { value: newTags.join(',') } }]);
    console.log('Done');
}

I guess it depends how many times that function gets called, but that doesn’t look “random”. That is 300ms.

I assume the delay is added so all the operations like creating a file, or writing to the cache have a chance to finish, and the order of operations don’t get clobbered. A lower delay might also work.

Have you timed the total amount of time you end up waiting?

Nope. Are you suggesting to use console.time or something else?

I’m not really suggesting anything. What’s the problem? Are you just asking why the delay helps? Or are you getting really long delays, and you’re trying to fix it?

I’m not sure what you’re looking for. You said “bum, it worked.” So is there still a problem?

the problems are:

  • it is not rational. It is just a specific amount of time (a magic number of 300) that means nothing for most people except for the one who choosed it
  • it is undocumented, so I can’t know if this is a real solution or more a coincidece
  • It may change at any time, without further notice and break my note-taking flow

Those are the problems

What may change? And how would it break your note-taking flow?

Also I don’t understand what you mean by not rational, or magic. It’s 300ms. 0.3 seconds.

1 Like

I believe that templater can remove that 300ms delay now. The reason was actually a problem in Obsidian core that was fixed a long time ago.

Basically, the daily notes core plugin would create an empty file, then modify the empty file with your daily note template.

The issue was that the ‘created’ event was fired before the daily note template was applied, so Templater needed to work around that issue.

I think that hasn’t been a problem since around 1.0 of Obsidian. Now all the core plugins create the file with the contents already applied in a single filesystem call.


That’s the history behind that magic number at least.

6 Likes

That’s a fantastic explanation, thanks

Appreciate the insight Liam, will add a fix to prevent the delay on newer versions of Obsidian.

2 Likes

This change affects the third-party plugins that rely on this behavior: fix: compatible with templater 1.6.1+ · quanru/obsidian-periodic-para@2cceb0f · GitHub