Select to view content in your preferred language

How do I style a feature layer by object field?

890
5
Jump to solution
06-11-2023 07:23 AM
נוהאליה
New Contributor

Hey , I have a geojson that in the attributes section for each feature I have an object that's called 'extras', like so (example geojson):

{
	"geometry": {
		"type": "Polygon",
		"coordinates": [
			[
				
				[
					00.76486274700005,
					00.903816257000075
				]
			],
			[
				[
					00.79834464800007,
					00.89163211700003
				],
			]
		]
	},
	"properties": {
		"objectid": 187,
		"extras": {
			"PHP_2021": "false",
			"PHP_2018": "true",
			"PHP_2019": "true",
			"PHP_2020": "true",
			"PHP_2022": "true"
		}
	},
	"type": "Feature",
	"id": 187
}

 

I also have this styling:

const renderer = {
            "type": "unique-value",
            "field": "extras.PHP_2021",
            "defaultSymbol": defaultSymbol.symbol,

            "uniqueValueInfos": [{
              "value": "true",
              "symbol": {
                "type": "picture-marker",
                "url": "../../assets/images/clicked-point.png",
                "width": "34px",
                "height": "38px"
              }
            }],
          };

That does not work because it can't read 'extras' as object.

Is there a way that I can use object (in this example 'extras' object) in order to render a feature layer?

thanks.

0 Kudos
1 Solution

Accepted Solutions
JoelBennett
MVP Regular Contributor

The flattening option mentioned by @LongDinh is most likely the way to go.  Perhaps you're not able to alter things on the server side, but you can on the client-side.  Check out this thread, and in particular, the second solution. Although the initial problem is somewhat different (i.e. popup content instead of rendering), the solution will still likely be along the same lines...i.e. using a RequestInterceptor and flattening the attributes so that your renderer can access them.

View solution in original post

5 Replies
LongDinh
Occasional Contributor II

Hi @נוהאליה ,

I had a look a the JS Docs and I don't think there's a clear implementation currently available.

However, there may be some solutions to try out.

My first suggestion is to attempt to use an Arcade Expression as part of your Unique Value Renderer to retrieve the $feature.extras.PHP_2021 value, e.g:

let renderer = {
 ...
 valueExpression: "When($feature.extras.PHP_2021, True)"
 ...
}

 

The second option is not very enticing. You could try flattening the extras and bringing the extras properties up one level into the properties array. Then, you can apply a renderer by each PHP_* field name.

Good luck!

נוהאליה
New Contributor

Hey, first of all thanks for trying to help me, second I guess I should have say that my first attempt was actually  arcade expression exactly how you wrote it but it didn't work because by the docs its says that the attribute can only be string or number not even Boolean  and not an object as well:

" Expressions in UniqueValueRenderer may reference field values using the $feature profile variable and must return a string or a number"

I also thought about flattening the properties one level up, but because the 'extras' is auto generated and it happening in C# it is very hard to do at least for my skills, because I have no idea how I declare auto generated properties in C# and I can't use dictionary for all the attributes because I need to use some of them, I guess I could use each place that I want to use the other attributes 'Try and Catch' but that is not the way I would like to do it.

thanks anyway though (:

JoelBennett
MVP Regular Contributor

The flattening option mentioned by @LongDinh is most likely the way to go.  Perhaps you're not able to alter things on the server side, but you can on the client-side.  Check out this thread, and in particular, the second solution. Although the initial problem is somewhat different (i.e. popup content instead of rendering), the solution will still likely be along the same lines...i.e. using a RequestInterceptor and flattening the attributes so that your renderer can access them.

LongDinh
Occasional Contributor II

@JoelBennett, that RequestInterceptor is pretty cool! Like an SOI but for client-side. Thanks for sharing 😃

0 Kudos
ReneRubalcava
Frequent Contributor II

Arbitrary object properties are not supported in GeoJSONLayer, listed under known limitations.

https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-GeoJSONLayer.html

  • Using Object as attribute value for GeoJSON features is not supported.