I have a UniqueValueRenderer assigned to a StreamLayer, assigning "valueExpression" as shown:
valueExpression: `
const featureStartTime = $feature.START;
const now = Date.now();
const TIME_TO_LIVE = 90000;
const timeSinceStart = now - featureStartTime;
const veResult = (timeSinceStart > TIME_TO_LIVE) ? 'expired' : $feature.GROUP_NAME;
return veResult;
`,
{
"declaredRootClass": "esri.arcade.lib.parsingerror",
"name": "ParsingError",
"code": "UnexpectedIdentifier",
"index": 22,
"line": 2,
"column": 22,
"len": 15,
"data": {
"value": "featureStartTime"
},
"description": "Unexpected identifier",
"range": {
"start": {
"line": 2,
"column": 21
},
"end": {
"line": 2,
"column": 37
}
}
}
Note about Accepted Solution: I accepted the solution based on the fact that it got rid of the error I report above. Here is the final implementation, fully functional thanks to invaluable tips from @KenBuja and @AnneFitz , in case anyone is trying to solve a similar problem:
valueExpression: `
var timeSinceStart = DateDiff(Now(), Date($feature.START));
var veResult = IIf(timeSinceStart > ${TIME_TO_LIVE}, 'expired', $feature.GROUP_NAME);
return veResult;
`,
Solved! Go to Solution.
Arcade is a basic language and doesn't understand "const". It only uses "var" to declare a variable. It doesn't understands the conditional statement as written. You'll have to replace that with an iif statement. I would recommend trying your expressions out in the playground to check your syntax
var featureStartTime = $feature.START;
var now = Date.now();
var TIME_TO_LIVE = 90000;
var timeSinceStart = now - featureStartTime;
var veResult = IIF(timeSinceStart > TIME_TO_LIVE, 'expired', $feature.GROUP_NAME);
return veResult;
Arcade is a basic language and doesn't understand "const". It only uses "var" to declare a variable. It doesn't understands the conditional statement as written. You'll have to replace that with an iif statement. I would recommend trying your expressions out in the playground to check your syntax
var featureStartTime = $feature.START;
var now = Date.now();
var TIME_TO_LIVE = 90000;
var timeSinceStart = now - featureStartTime;
var veResult = IIF(timeSinceStart > TIME_TO_LIVE, 'expired', $feature.GROUP_NAME);
return veResult;
I copy/pasted your version of function (replace const with var; replace ternary with IIf) and I am now getting a new error:
"RemoteClient.js:1 [esri.views.2d.support.arcadeOnDemand] Feature arcade evaluation failed: Error: Execution error - Function not found".
Everything @KenBuja said is 100% right, thanks Ken! I also wanted to point out that Date.now() will not work in Arcade, instead use the built in Arcade function Now() . Also instead of subtracting the dates, I would use the built in DateDiff() function. Hope this helps!
I also forgot to add that "now" is a reserved word and shouldn't be used as a variable name
@KenBuja @AnneFitz -- Your combined suggestions got me past the errors that were being logged to the console. I'm still not seeing the "expired" result being returned, even though I know I have expired features in the layer, but that's another problem. You gave me the answer to fix the error I was seeing. Thank you both very much.
As an aside, is there any way to console.log what the renderer is returning for "value" for any given feature? I know I can't put a console.log inside of the valueExpression.
I used this script in the Playground to get "expired", using a Popup profile with its available fields. In the Playground, you can use Console to see intermediate variables.
var featureStartTime = $feature.LASTUPDATE;
var TIME_TO_LIVE = 90000;
var timeSinceStart = DateDiff(Now(), featureStartTime);
console(timeSinceStart, DateDiff(Now(), featureStartTime, "minutes"))
var veResult = IIF(timeSinceStart > TIME_TO_LIVE, 'expired', $feature.LASTEDITOR);
return veResult;
Note that anything more than about a minute and a half would be expired.
so, in my running code, passing $feature.START to "console()" logs an epoch ms value, whereas passing result from call to DateDiff() is logging null for some reason. Obviously, I'm hosing that somehow, but I feel like I'm closing in on this.
As far as I'm concerned, that "console()" function is the real breakthrough for me. 50% of my debugging is in the debugger and the other half is with console.log() statements. You can't put a breakpoint in an Arcade expression, and I had no clue how to log the intermediate results. I felt like a turtle on my back. I feel like I have a chance to figure this out now. Thank you for showing me that.
I see the problem. Now() returns Date object, formatted according to locale, whereas $feature.START is a number -- epoch ms. DateDiff() only takes Date objects for it's arguments, so I need to turn $feature.START into a Date before passing it to DateDiff().