Linking to several notes based on a set-based attribute

Dear all, I am a bit rusty with Tinderbox, and not using it much lately. Still, I tried doing the following today:

  • I have an “event_p” prototype with a “Link” Key Attribute (of “set” type);

  • I have an “events” container which has several original notes of that prototype (“A”, “B”, “C”, “D”, “E”);

  • I have an agent “events collector” that pulls all notes from the “events” container and automatically tries to link them, using its “action” code which is the following:

if ($IsAlias & $Link) {linkTo(find(inside("events collector") & $IsAlias & Name==($Link(that))),"");};

This works only if one value is present in the events’ “Link” attribute: i.e., if note “A” has “B” as value in its “LINK” key attribute, then the agent will execute its action correctly and link “A” to “B”; but if note “A” has “B;C” as its value, nothing gets connected.

I was expecting the agent action to loop through the aliases of notes “B” and “C” inside the “events collector” container and link “A” to them.

All help is appreciated, thank you! Maybe using each() someway?

Sadly too busy to try a worked example, but the breakage is likely this clause:

$Name==($Link(that))

‘==’ is an exact, case-sensitive (if a string), match. Thus

"A"=="A"

Is true but:

"A"=="A;B"

Is false. A is part of A;B. Do if comparing strings that may be lists, use .contains() or .icontains(). Thus, I’d replace

$Name==($Link(that))

with

$Link(that).contains($Name)

This should see if the $Name of any queried note exists within the string representing the whole list value. IOW, it tests if

"A;B;C".contains("A")

Of course if you have to watch for collisions:

"A;AB;C".contains("B")

is true as the match is substrings of the whole string and not against parsed-out list values.

Another approach is something like (N.B. untested code):

if ($IsAlias & $Link) {
   $Link.each("listValue"){
      linkTo(find(inside("events collector") & $IsAlias & $Name==listValue),"");
   }
};

Here, because listItem as always a single note $Name, we can use a == comparison.

Tested at last. Slight tweak:

if($IsAlias & $Link){
   $Link.each(listValue){
      linkTo(find(inside("events collector") & $IsAlias & $Name==listValue));
   };
};

My earlier mistake was to put quotes around the name of the iterator used by .each().

1 Like

Thank you, works perfect. This kind of subtleties make TBX pain…great!