Is this best way to get parents() of an element?

Started by Manj75, September 28, 2021, 12:36:59 PM

Previous topic - Next topic

Manj75

I'm trying to get the parents of elements and I know that the method is only available on Collections.  I have implemented this as follow but it is slow running and was wondering if there is a better way to do it.  The code below is illustrative but the actual use case is to traverse the element parents and build a full path string.


// Loop through all elements in the model that are of type element
for (e of $("element")) {

  // Get a Collection of the parents for each iterative element
  var elementlParents = $("element").filter("." + e.name).parents()

  // Loop the parents to pull out each parent traversing up the model
  elementlParents.each(function(elParent) {
    console.log(">> parent" + elParent)

  })
})


Using this code it runs slow because it's is traversing up the parent folders for every element in the model and this may be valid.  I just wanted to know if this is the only to do this or are better suggestions.

What I can see is that I am looping to find each 'element' for which I then create another Collection using filter to find the same element again only to return me it's parents.

Jean-Baptiste Sarrodie

Hi,

Unless there's something I don't get in your use-case, you can get parents of an element named E with:
Quote$(E).parents()

JB
If you value and use Archi please consider making a donation! https://www.archimatetool.com/donate

Manj75

September 28, 2021, 16:17:58 PM #2 Last Edit: September 29, 2021, 08:01:29 AM by Manj75
Please go easy I'm not a javascript expert and am learning a long with learning jArchi :)

JB - I presume in your given example you are referring to E as a substitution of the element.  If so this is what I started with, however, the element is an object rather than a collection for which I get parents() is not a method of element.  Ideally I'd want to do something like:


$("element").each(function (e) {
var parents = e.parents()
})

Results in: TypeError: e.parents is not a function (I know because e is an EObject and parents() is not a method of this)


Anyway, the actual use case is that the client wants to capture the full path of the elements and I've developed this as follows - I just wanted a view of whether there is a better way to do it.


function getElementFullPath(el, includeElementName = true)
{
const pathDelimitter = '\\'
let elParents = $("element").filter("." + el.name).parents()

let elFullPath = ""

if (includeElementName)
elFullPath = el.name

elParents.each(function(elParent) {
elFullPath = elParent.name + ((elFullPath == "") ? "" : pathDelimitter) + elFullPath
})

elFullPath = model.name + pathDelimitter + elFullPath

return elFullPath
}

for (e of $("element")) {
console.log(">> element full path: " + getElementFullPath(e))
}


If there's no alternative suggestion then I just stick with what I have

Jean-Baptiste Sarrodie

Hi,

Quote from: Manj75 on September 28, 2021, 16:17:58 PM
JB - I presume in your given example you are referring to E as a substitution of the element.  If so this is what I started with, however, the element is an object rather than a collection for which I get parents() is not a method of element.  Ideally I'd want to do something like:


$("element").each(function (e) {
var parents = e.parents()
})

Results in: TypeError: e.parents is not a function (I know because e is an EObject and parents() is not a method of this)


Look carefully ;-)

I wrote

$(E).parents()


not

E.parents()


To use a collection-only method on an element, you simply have to create a collection containing this element, and this is as simple as
$(your_element)

Re getting the full path, in fact I shared a snippet some time ago on the forum, so you can achieve your goal this way:


function createPath(currentPath, currentObject) {
  return "/" + currentObject.name + currentPath;
}

function getPath(obj) {
  var pathCollection = $(obj).add($(obj).parents());   // Get a list of object and its parents
  var path = Java.from(pathCollection).reduce(createPath, "");   // Convert the (java) list to a (JS) list and reduce it with the 'createPath' function
  return path;
}

// Using each() simply because on my current PC I have only access to an old version of jArchi
$("element").each(function(e) {
console.log(">> element full path: " + getPath(e))
});


Regards,

JB
If you value and use Archi please consider making a donation! https://www.archimatetool.com/donate

Manj75

The penny drops - this is fantastic really helps me in many of my scripts that I've created.

Basically, converting the element to Collection is done by specifying it in the $().  Wow this will be so useful.

JB - many thanks for the detailed explanation and for your patience :)

Btw - your suggestion for getting the full path for elements is great and I can see it is optimised and runs fast.

Jean-Baptiste Sarrodie

Hi,

Quotemany thanks for the detailed explanation and for your patience

You're welcome.

Many thanks for pointing this out. I've just noticed that it was not well documented so I've just made it clear on the wiki.

Regards,

JB
If you value and use Archi please consider making a donation! https://www.archimatetool.com/donate