Action-setfield $index witout $tiddler bug

Hi!

In my programming, I had often created a nasty bug with a coding such as

<$action-setfield $tiddler=<<source>> $index=<<memo>> $value=<<value>>/>

where, in fact, the source variable is empty. This lead the text of the current tiddler to be replaced with something like:

{
   "my memo": "my value"
]

and its type being set to json content. Quite nasty, especially erasing your current tiddler code.

I cannot see any real use case where you would set an index to tge current tiddler. If indeed there is none, then it would be best to forbid setting an index if the tiddler is not specified. But if there were such cases, then I would say it would be really welcomed to have a global setup indicating NOT to create an index if the $index field is either not specified or empty.

(yes, the original bug is my fault, where <<source>> should not be null. But the current situation just add problems. And since I want a complete liberty in the index name, fields is not an option, for some names are reserved, and I cannot be 100% sure a naming convention will be always respected (such as prefixing name with “@”).)

The value of <<currentTiddler>> can be set by the surrounding wikitext code.

For example, you could have a <$list> widget that finds all tiddlers with a type of application/json and a prefix of “settings/”, and then add a timestamp index to those tiddlers:

<$list filter="[type[application/json]prefix[settings/]]">
   <$action-setfield $index="timestamp" $value=<<now "YYYY0MM0DD0hh0mm0ss0XXX">> />
</$list>

while this example may be a bit contrived, it is perfectly valid. Of course, it might be better if the $tiddler param was explicitly specified (i.e., $tiddler=<<currentTiddler>>), but it shouldn’t be required.

This also applies to a common code pattern, where a macro is defined to operate on the current tiddler, with the assumption that the <<currentTiddler>> value is set outside the macro, like this:

\define setTimestamp() <$action-setfield $index="timestamp" $value=<<now "YYYY0MM0DD0hh0mm0ss0XXX">> />
<$list filter="[type[application/json]prefix[settings/]]"><<setTimestamp>></$list>

-e

Agreed. It’s extraordinarily painful. I posted an issue to Github about this. The very least we could do is improve the error detection and thereby improve the UX around missing/critical values.

It’s happened to me on two occasions – never in tested/released code, only ever in cases where I’m throwing together a proof of concept and suddenly lose all the work due to a dumb typo in <<mistyped-varname>> or similar.

In no way the full solution however consider using the following for the tiddler parameter.

$tiddler={{{ [<source>else[source-error]] }}}

However along the same line of Erics suggestion perhaps wind back to where the source variable is is provided such as in a macro call.

\define macro(source)
<$set name=source value="$source$" emptyValue="NotCurrentTiddler">
...
<$action-setfield $tiddler=<<source>> $index=<<memo>> $value=<<value>>/>
...
</$set>
\end
<<macro source>>

In this example we are doing more to validate or set the value before use.

From a practical perspective as a coder let us commit to memory that "when using the $index parameter, especially in set widgets, you need to add a validation test at least for the $tiddler parameter.

Whilst this also can be true selecting a $tiddler= in action widgets without the index perhaps we are more likely to be more aware of the currentTiddler value in those cases.

Note: Some of Tiddlywikis core macros have a similar problem.

Yea, I know this problem too. … That’s 1 more reason to have a good backup workflow, especially during development.

The positive side of things is, that the code I do after an accident often is better than the one I had before :wink:

Yes, I recall you commented at the time I posted about.

Very true!

But it can still really “P**s one off.”

All the recommandations posted are good and honest. But when facing a disaster, it is not the best pracitices that will save you when bad things will happen. Do whatever code check you want, a typo will distroy them. For instance, you check fubar with great care, but in the performative part, you type fubarr and all is lost!

The only way to be sure of fubar is to type it just once! So this mean that it is up to the inner code of the action-setfield widget to check for it.

It’s in the works:

@CodaCoder Great! “only fall back to using currentTiddler for the target if the $tiddler attribute is entirely missing, and not if it is blank.” is really what I need and that’ll be a fine solution for everyone, I think.