Issue with geojson layer in Perspective Map

I am having an issue with Perspective Map and I wanted to see if anyone else has experienced this:

If I have a Map and I manually create the structure:

The map loads fine.

If I bind features to anything and hit save, the map, in both the browser and designer, will show

with the error: can't access property "length", s.features is undefined. This is also shown in the js console.

If I reload the web page it works again. It seems to only break on designer save.

If I set the prop to Persistent, that also seems to fix it.

Binding lower level props or the whole array (layers.other.geoJSON[0]) also seems to work fine.

Any thoughts? I’ll try sending this to support soon if this isn’t a me thing

I should add that the reason I want to bind features specifically is that this is easy to get from Postgresql, and I want to have a styleOptions field. Its nice when this field is known to Designer, rather than being set from a script, so that its easier to use

Bindings that require a callout to a DB or across the network will supply a null until the data arrives. You should place the binding on a custom property, and use coalesce() to substitute a default value for features until the null is replaced.

1 Like

ahh, perfect! I thought there would be an easy way to do this. Thank you!

1 Like

Sorry for an additional late reply, I had an alternative but worse solution when I posted this, and I’ve just gotten around to trying this properly.

I can’t get coalesce to work, or a script checking for None. I have the binding on a separate custom property as suggested, then I’ve tried:

  • using using a property binding to get it onto layers.ui.other.geoJSON[2].features, with a transform
  • using an expression binding with coalesce directly

As a test, I tried both of these targeting a binding of a blank array.

The only way I can get a binding (at the features level) to work is by also setting the feature to be persistent

I can't read your mind nor see how you applied or misapplied the coalesce() function. Show us.

Absolutely. I apologise as well for the infrequent replies, I’ve been under a bit of a time crunch. I’ll try and get you screenshots/code blocks. Thank you!

Thank you for your time and patience.

Here is a Map, with layers.other.geoJSON.0.features bound on the right:

I have this.custom.array as just an empty way as I wasn’t sure of the best way to return an array from this.

this.custom.features is bound to:

Upon saving this in Designer, the can't access property "length", s.features is undefined occurs. Refreshing the the browser does occasionally work, but not permanently.

I have also noticed this is happening on bindings just to custom tags: element with the binding is not persistent, it does not seem sticky.

I have a few things with nested flex containers that have position.display bound to custom.on. The custom is set to false. I’ve tried the display binding as just property and as an expression with: coalesce({this.custom.test}, false). This appears to not be working because there is no value on first load (of position.display ) without persistent being set. Setting persistent allows the desired behaviour, which is no flashing on loading the view. This does not seem ideal, as this code is stored in git.

Any insight into how I’m using this wrong with what I’ve posted, or should I start talking through official channels?

There is a brief window between position.display being evaluated (which will be true with persistence off) and when the custom properties are evaluated.

Not sure if this is best practice, but since you seem to want to avoid any persistent properties, my thought is you could create a startup script for this view that sets a custom property called initialized to True. This property doesn’t need a binding or a persistent value, and it will be null until the script sets it.

Your binding on position.display would be this expression:

coalesce({this.custom.initialized}, false) && coalesce({this.custom.on}, false)

The unresolved state of both properties coalesces to false, so the component remains hidden until both resolve. This is untested but maybe worth a try.

Thank you for your response!

I had position.display = coalesce({this.custom.test}, false), which seems like if the custom property hasn’t been evaluated, position.display will be false, like what you have suggested. But this isn’t what I have observed unfortunately.

but since you seem to want to avoid any persistent properties,

I’m okay with a persistent value in this case, I just brought it up to help show that I can’t get coalesce to work. It is only for the db queries that persistent bothers me, cause that could be lots of data

Yeah, if your current solution with coalesce doesn’t do it, what I posted wouldn’t functionally change anything. I have run into this issue a few times myself, and I think I was able to fudge it by applying a style class that fades in from 0% to 100% opacity. In the meantime I find myself having to make sure all my persistent values are set correctly before I save my projects, which is an extra step and prone to error here and there. Maybe you could look into mounting your query result somewhere else where this project can read it, instead of polling right then and there. Alternatively a startup script that writes initial values may work as well.

Yeah, my workaround for the large db datasets is a script that reads from a binding and writes it over the correct prop.

I was hoping that @pturmel would be able to show me a mistake with the bindings to avoid that, as this seems likely to be a frequent thing to do, but you have said implies otherwise. Ahh, well, I shall stick with workarounds.

Thank you for your input!