Archi Forum

Discussion Boards => jArchi => Topic started by: Manj75 on September 28, 2021, 12:36:59 PM

Title: Is this best way to get parents() of an element?
Post by: Manj75 on September 28, 2021, 12:36:59 PM
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.
Title: Re: Is this best way to get parents() of an element?
Post by: Jean-Baptiste Sarrodie on September 28, 2021, 12:49:41 PM
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
Title: Re: Is this best way to get parents() of an element?
Post by: Manj75 on September 28, 2021, 16:17:58 PM
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
Title: Re: Is this best way to get parents() of an element?
Post by: Jean-Baptiste Sarrodie on September 28, 2021, 19:02:06 PM
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 (https://forum.archimatetool.com/index.php?topic=976.msg5311#msg5311), 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
Title: Re: Is this best way to get parents() of an element?
Post by: Manj75 on September 29, 2021, 08:17:32 AM
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.
Title: Re: Is this best way to get parents() of an element?
Post by: Jean-Baptiste Sarrodie on September 29, 2021, 12:02:40 PM
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 (https://github.com/archimatetool/archi-scripting-plugin/wiki/jArchi-Collection#-jarchi).

Regards,

JB