createYamlProperty can not create multiple properties
panwanke opened this issue · comments
When I use metaEditApi.createYamlProperty, It can only create one property.
When using forEach
or loop function
, the createYamlProperty just create one meta property, and the posterior property would cover the prior.
When I set timeout or seperately ran this function, it maybe create multiple properties but with multiple dividers.
Please provide some APIs that can be used to create or update more diverse properties.
Did you ever figure out the problem? I'm able to create multiple properties in a loop without any problems.
I've had a similar issue with this plugin before, and I realized that it was caused by missing a single await
statement when calling one of the api async functions. I was also able to recreate an incorrect output with multiple dividers (like you described) when I ran a createYamlProperty
loop without using await
.
You may have already done this. but check to make sure you didn't miss an await
when calling the createYamlProperty
function, other async functions from the api, or async functions used from your own scripts.
If that's not the problem, I may be able to help if you provide some more details like your code/output/expected output.
I can duplicate this, when using metaedit as part of a templater template (edited to add: this is on Win10).
I'm trying to set up a templater template that uses the metaedit api to create multiple frontmatter fields. Creating a single property works as expected. In practice I want to do some logic but for testing purposes I'm running:
<%*
const {createYamlProperty } = this.app.plugins.plugins["metaedit"].api;
var active_file = await app.workspace.getActiveFile()
await createYamlProperty('AB', 1, active_file);
-%>
This works as expected, outputting
---
AB: 1
---
Note Content
But, I would like the templater template to create multiple properties at once. As in the earlier reply, I'm being careful to await everything:
<%*
const {createYamlProperty } = this.app.plugins.plugins["metaedit"].api;
var active_file = await app.workspace.getActiveFile()
var ab = await createYamlProperty('AB', 1, active_file );
var bb = await createYamlProperty('BB', 1, active_file );
var cb = await createYamlProperty('CB', 1, active_file );
-%>
I would expect this to produce the following:
---
CB: 1
BB: 1
AB: 1
---
Note Content
...and it very rarely does produce that, but usually I get:
---
CB: 1
---
---
BB: 1
---
---
AB: 1
---
Note Content
This suggests that there is some timing error happening where the frontmatter is being created three times. There are also occasional intermediate cases where AB and BB are created in one frontmatter, and CB in a second.
I have also tried wrapping the property creation in an async function, as well as using a for loop. There are also occasional intermediate cases where AB and BB are created in one frontmatter, and CB in a second.
This bug seems to occur in the file with notes below the fronmatter.
For creating a new file, I have not encounter with this probelm.
But for the existing file, I occasionally get the same issues:
---
CB: 1
---
---
BB: 1
---
---
AB: 1
---
Note Content
Or get many blank lines:
---
CB: 1
BB: 1
AB: 1
---
I have the same issue, hoping to create multiple front matter properties. My template is
<%*
const {createYamlProperty} = this.app.plugins.plugins["metaedit"].api;
await createYamlProperty("note-due", tp.date.now("YYYY-MM-DD"), tp.config.target_file.path);
await createYamlProperty("todo", true, tp.config.target_file.path);
%>
Yup. I got the same. However, my initial YAML was created by DB Folder.
I even put some delays between the calls.
I also have other functions where I use meta-edit's API to update or create values...
If this is not fixed, I will have to create my own variant for myself... Because this is absolutely vital for my task manager, even a margin of 10% of cases where it happens can be catastrophic.
async updateMetadata(updatedEvent) {
const waitAmount = 100
let newStartDate = new Date(updatedEvent.start);
let newEndDate = new Date(updatedEvent.end);
let newColor = updatedEvent.extendedProps.color;
let newDescription = updatedEvent.extendedProps.description;
console.log(newDescription);
let formattedStartDate = formatDate(newStartDate);
let formattedEndDate = formatDate(newEndDate);
let datePropName = updatedEvent.extendedProps.datePropName;
let colorPropName = updatedEvent.extendedProps.colorPropName;
let descriptionPropName = updatedEvent.extendedProps.descriptionPropName;
let path = updatedEvent.extendedProps.note.file.path;
// Delays are essential because of an issue with meta-edit where changes do not persist with consecutive edits.
// See: https://github.com/chhoumann/MetaEdit/issues/83
await update(datePropName, formattedStartDate, path);
await new Promise(r => setTimeout(r, waitAmount));
await update(`${datePropName}_End`, formattedEndDate, path);
await new Promise(r => setTimeout(r, waitAmount));
await update(colorPropName, newColor, path);
await new Promise(r => setTimeout(r, waitAmount));
await update(descriptionPropName, newDescription, path);
}
async getId() {
let id;
if (this.note.id === undefined){
id = UUIDv4();
await createYamlProperty("id", id, this.note.file.path);
}
else if (this.note.id == null)
{
id = UUIDv4();
await update("id", id, this.note.file.path);
}
else if (this.note.id === "")
{
id = UUIDv4();
await update("id", id, this.note.file.path);
}
else
{
id = this.note.id;
}
return id;
}
async getEventColor(defaultColor = "rgb(117, 117, 117)") {
let colorString = await getPropertyValue(this.colorPropName, this.note.file.path);
if (colorString === undefined) {
await createYamlProperty(this.colorPropName, defaultColor, this.note.file.path);
// console.log("Undefined color for: " + this.note.file.name + " created: " + defaultColor);
return defaultColor;
}
else if (colorString == null) {
await update(this.colorPropName, defaultColor, this.note.file.path);
// console.log("Null color for: " + this.note.file.name + " updated: " + defaultColor);
return defaultColor;
}
else if (colorString === "") {
await update(this.colorPropName, defaultColor, this.note.file.path);
// console.log("Empty color for: " + this.note.file.name + " updated: " + defaultColor);
return defaultColor;
}
else {
// console.log("Filled color for: " + this.note.file.name + " retrieved: " + colorString);
return colorString;
}
}
async parseStartDate() {
let dateString = await getPropertyValue(this.datePropName, this.note.file.path);
if (dateString == null || dateString === "") {
let date = new Date(); // Assign current date and time
await createYamlProperty(this.datePropName, formatDate(date), this.note.file.path);
return Date.parse(date);
}
return Date.parse(dateString);
}
async parseEndDate() {
let dateString = await getPropertyValue(this.datePropName + "_End", this.note.file.path);
if (dateString == null || dateString === "") {
let date = await this.parseStartDate();
date = await this.getEndDate(date, 0, 30); // Assign default duration of half an hour
await createYamlProperty(this.datePropName + "_End", formatDate(new Date(date)), this.note.file.path);
return Date.parse(date);
}
return Date.parse(dateString);
}
async changeColor(colorString) {
await update(this.colorPropName, colorString, this.note.file.path);
}
async getEndDate(endDate, hours = 0, minutes = 0) {
try {
// If endDate is a timestamp (milliseconds since epoch), convert it to a Date
if (typeof endDate === "number") {
endDate = new Date(endDate);
}
if (endDate instanceof Date && !isNaN(endDate)) {
// Calculate the end date by adding hours and minutes to the start date
endDate.setHours(endDate.getHours() + hours);
endDate.setMinutes(endDate.getMinutes() + minutes);
// Format the end date as a datetime string (e.g., "YYYY-MM-DDTHH:mm:ss")
return formatDate(endDate);
} else {
console.error("Invalid start date:", endDate);
return null; // Handle invalid start date gracefully
}
} catch (error) {
console.error("Error parsing start date:", error);
return null; // Handle errors gracefully
}
}
async getDescription(defaultDescription) {
let description = await getPropertyValue(this.descriptionPropName, this.note.file.path);
if (description === undefined){
description = defaultDescription;
await createYamlProperty(this.descriptionPropName, description, this.note.file.path);
}
else if (description == null)
{
description = defaultDescription;
await update(this.descriptionPropName, description, this.note.file.path);
}
else if (description === "" && description !== defaultDescription)
{
description = defaultDescription;
await update(this.descriptionPropName, description, this.note.file.path);
}
else
{
return description;
}
}