[IGN-6092]Array in Expression Transform

When I need to show a value that might not always be present, often I will just do coalesce statements in expressions like coalesce({view.params.myOptionalParam}, '') to show the value without an overlay if its not present (I do want the overlay if its present and bad quality)

However when I need to do this for a list or object I have only really found it possible through a runScript, is this really the only way?

Array:
coalesce({view.params.myListParam}, runScript("[]"))

Object:
coalesce({view.params.myDictParam}, runScript("{}"))

I would like to think that since perspective is so heavily built with objects and arrays there is a cleaner way to do this? Almost feels like there should just be a simple set of two expressions in perspective for Array() and Object() that take params to build the two or something.

Not easier or cleaner, but I guess if you wanted to avoid using runScript you could make empty array/object session props and return those instead ?

I kinda hope there’s a better way though.

1 Like

That's an interesting idea.

Literal [] and {} are probably not going to happen, but I could see arrayOf and objectOf functions (or something similar).

Outside of this coalesce example, can you name any times you would have wanted to build an array or object entirely within an expression? Not to say that it's not a good idea, I'm just curious what the use cases would be.

1 Like

Most use cases I can immediately think of I could solve with an expression structure, its just the default typing that I can't. For me its primarily to do the same thing as a dict.get(myVal, defaultVal) so that I don't have components erroring out from receiving nulls instead of empty objects or lists.

But I would guess that with how deeply intertwined with perspective arrays and objects are, there have got to be other uses I am not thinking about.

EDIT: In order to do what is mentioned above with an expression structure, I would need to do an expression structure with my value, and then another with the default structure, and then do an expression transform afterwards that coalesces them together. Still feels a bit extra like the runScript

Today I found myself needing to create a test array for the Tree component with a binding. Realising that the expression language couldn’t do it I set the expression to null and then applied a script transform which didn’t even look at value but just generated the dictionary with Python. (So I guess I have a workaround?!)

I actually just helped another engineer that could have used this.

He had a popup that needed a list of tag paths, and a specific view that called it and only ever was going to provide one tag path.

So instead of just having his parameter of tag path, in order to provide the popup what he needed he would indirect view.params.tagPath into another object that was just structured as a list with a binding on index 0 to read the parameter. This could have been a lot easier if he could just use an expression of something like arrayOf({view.params.tagPath}) and then it would have cut down on unnecessary middle man bindings slowing things down. I think that’s where this would shine, is the ability to remove extra bindings and transforms for small data manipulations.

1 Like

I’m sold, I made an internal feature ticket for it. I can’t guarantee it’ll be picked up, but I’ll make the case :slight_smile:

2 Likes

this seemed like it should work to return a list:

jsonGet("{'fruit':['Apples','Oranges','Grapes']}",'fruit')

instead, it seems to just return:

['Apples','Oranges','Grapes']

as a string?

That's odd. When I try it all the single-quotes show up in the binding preview as double-quotes - so it's not handling it as a literal string yet a script transform with return type(value) shows class org.python.core.PyUnicode as though it is a string!?

image