Unlinking Notes via Actions

In an agent, I am trying to create actions that delete all links to/from the notes returned by the query. I am using:

unlinkFromOriginal(all,"*");
unlinkToOriginal(all,"*");

This does not seem to work.

I have been reading forum posts, documentation, and have tried multiple approaches.
Any thoughts on what I could be missing?

Thanks!

I tried using:

unlinkFrom(all,"*");
unlinkTo(all,"*");

And still no effect.

I think I’m not understanding something about how Tinderbox works. I tried the unlikFromOriginal(s) because on other posts it stated that you should use those when unlinking in an Agent action as opposed to a Stamp.

I have an agent that collects all notes that are $Completed==true and moves them into a container. It’s doing that successfully, but the unlinking doesn’t seem to work.

The part that I think is confusing me is the pattern matching for all links regardless of origin/destination.

I would first try deleting a specific link to see if it works, then generalize.
Ex from aTBRef:
unlinkFrom(all,"note");unlinkTo(all,"note+");

In addition, I see an empty string and curly quotes. Both are not valid. IMO

unlinkFrom(all,“*“);

Tom

The (un)linkTo/From(Original) family of actions operate on basic links.

You are correct to use unlinkToOriginal()/unlinkFromOriginal() if trying to run code via an agent alias, as the point is that the deleted link(s) are between aliases

But testing just now in v9.7.3 the above actions work when run as a stamp on the original. But, they don’t seem to work when run in an agent. Why is unclear. They used to work so I guess some gremlin has crept in.

My test looks like this:

The agent action should work.

I’ve checked and fixed the formatting of code in previous posts as the curly quotes are rendering errors and not as typed in the source.

Do delete links of all link types, the second argument is"*". Why? Because it is actually a regex and "*" is evaluated as matching any value at all (i.e. any link type name).

†. Before someone notes it, I think "*" is being treated as if ".*", i.e. zero or more characters of an value.

  1. I don’t think that the unlink operators accept the wildcard for pathnames.

  2. unlinkFromOriginal(all,...) would delete all the links in the document. I think your agent wants unlinkFromOriginal(this,...);

Re-testing in v9.7.3, I find evidence of a different behaviour. This involved some amount of testing and spelunking of pre- and post-v6 Release notes (RNs), and my trove of >14.6k emails from beta-testing and forum support over the years. From the RNs:

  • pre-v6:
    • v4.6.0, $seq values 1683, 1684, 1702.
    • v5.9.0, $seq value 2631.
      *v6+:
    • v6.5.0, b175.
    • v8.1.0, b386, b387, b394.
    • v9.6.0, b611

It appears the unlinkX and linkX behave differently with regards to the second operator argument (linkTypeStr). It appears to be that:

  • linking operators. The linkTypeStr is optional; its value is parsed as a literal string. If not supplied the link created is of type untitled (link type “*untitled”).
  • unlinking operators. The linkTypeStr is mandatory; its value is parsed as a regex string. The string "*" is used (only for unlinking) as a placeholder for all link types and none.

The ‘Original’-suffixed versions of the above are the same but seek to (un)link using the Original. But a weakness in agent use is that if the target links are original-to-original (i.e. no alias involved), the alias in the agent doesn’t seem able to delete links.

Here ‘To’ is outbound links from the acted on note, and ‘From’ is inbound links into the acted-on note. Note that normally (via the UI) we can only see the detail of outbound links (in Browse Links). Roadmap view shows both in-and out-bound links but only the link and its type, the link itself cannot be modified in the Roadmap.

I think the answer to that problem is to use .eachLink(loopvar,scope){} on a list of notes of intetest. That list would likely be made using a a find() or collect().

Note the unlinking commands cannot use $Path data, although ops like find() return $Path data, so the user is best using the $ID from the path in the .eachLink() loop when using unlink commands.

The Tinderbox Help file does little more than list the linking op names so aTbRef is standing proxy for Help here. My strong feeling is my notes are incomplete wrong in these regards:

  • linking and unlinking ops ‘look’ the same but actually are caled differently (e.g. arguments being optional vs mandatory)
  • there is no agent based way to ''unlink everything", though for the occasional user, agents are the obvious way to apply action code to desired groups of notes. List.eachLink() fills that gap but isn’t simple action code use.
    • My article on the latter op doesn’t have a fully worked example of ‘unlink all’ such as a starting user would need.

But, before I start a non-trivial edit across a aTbRef, could @eastgate confirm if the above is correct and there isn’t anything else missed? … or just wrong!

†. It is possible, manually, to make a link with no link type value (ironically discovered by a scripting accident), but this is not intended or suggested. Tinderbox expects links to have a link type. Whether the link type is visible as a label in views drawing links should be controlled by the label visibility labeled setting (the latter is also accessible to action code.l

I’ll revisit this and try to rationalize it. Give me a day or two.

1 Like

This is the type of link I am attempting to remove. The notes are not in any containers and they are linked together, both originals. I am trying to move them into a container and delete any links when I check a boolean attribute. Everything works except the removal of links. I am using an agent with a query to select the notes and actions to change the container and remove links.

Thank you so much for your research on this, quite impressive!

Do you perhaps know of a simple way to log the contents of a variable in actions during execution? That would help in debugging. I have found some examples of logging in Tinderbox, but they seem very verbose and involve lots of formatting, etc.

Thank you again. I will try your suggestion and report back!

So, on removal from the current (container) root you want to delete links. Inbound, outbound or both. IOW, if A is linked to B or B to A in your starting context/map and B is moved to a new container. Do we remove both links or only the outbound one from B?

I ask as it has some bearing on a possible solution.

Aside, …

So they are at document root? A top tip: although allowed it is a really good idea to build out your info under a container. We all tend to use root because that’s where the default views are. Over time I’ve found it better to only have at root what must be at root (e.g. for export purposes, etc.).

1 Like

They are at document root. Thanks for the tip! I will re-organize accordingly.

The idea is to remove all links. The thought is to clean-up anything extraneous and just have an actionable note archived as completed.

That you for your time and efforts on this. Very much appreciated!

Ugh — unlinkFrom/To is broken in this build, as @mwra revealed so clearly. Will be cleaned up shortly.

1 Like

OK, so the last post above shows there is a glitch at present and linkToOriginal()/linkFromOriginal() should work but don’t at present. A work around (tested in v9.7.3) is yo add the folllowing code to the OnAdd action fo the containers into which you are moving your notes out of the root:

unlinkFrom(all,"*");
unlinkTo(all,"*");

The simplest way to do this is to select the container(s), open the Action Inspector, action tab, and paste in the above code.

In the next public release you should be able to revert back to using an agent (but do check the release notes when it comes).