Descending into JavaScript objects sent as part of event details in EventCatcherWidget

Hi folks,

I have a project where I’d like to get values out of a keyed object that’s passed to event-detail-foo. Using the ActionLogWidget, the debug description is simply [object Object].

It seems like this ought to be possible with jsonindexes and friends (at least for simple JSON-codable types), but jsonindexes on my event-detail-foo seems to return an empty string.

Is there a TiddlyWiki-native way to access the values associated with a JavaScript object? If not, how might someone accomplish this in a Wiki?

Don’t think so. jsonindexes works with strings, not raw JavaScript objects.

You could petition @jeremyruston to add something like jsonindexes:rawobject[].

Not exactly ideal, I know, but you could write a JavaScript macro to return JSON.stringify(event.foo);

What is it in the event object you need access to?

EDIT: maybe @saqimtiaz has some insigth/thoughts.

I’m integrating an external JavaScript library (A-Frame) that sends information in the data of posted events. To get the clicked object (not a DOM object), I need access to event-detail-intersection (which is [object Object] without some way to descend into it).

I tried writing a JavaScript macro, but it doesn’t seem to execute in my wiki. Do I need to change a setting to allow it to run? Or is the another way to extract the data out of the event?

Add a field on the js tiddler, module-type, set it to macro.
Set Type to application/javascript
Then reload your wiki.

Don’t forget this! I spent an hour yesterday trying to figure out why something didn’t work… only to realize that I wasn’t saving after changing a JS module.

Awesome - this worked! Cool that it’s easy to extend TiddlyWiki with some JS. It’d be cool to someday do this in Wikitext, but I’m glad to have a solution.

@Scott_Sauyet - good reminder. The process slows iteration (as you have to reload), but it’s possible.

Hi @Peter I’m glad you got things working. I do wonder if it might not be worth making a minor improvement to the core here. Instead of returning object properties of the event object as the string “[object Object]” we could instead try to return the object as JSON. We wouldn’t be able to use plain JSON.stringify() because of the risk of there being properties that can’t be encoded in JSON, including circular references. So I think we’d have to use a handrolled utility that walks object properties and stringifies them to JSON, with plenty of error checking and fallbacks.

One potential pitfall is that all of that processing might take a non-trivial amount of time if the object being passed contains a large number of nested properties. It would be nice to be able to defer the computation until it is required.

That is easy enough to do in modern JS, even with plain dot property access, without adding any functions to the interface. But the technique I know was specified in ES5, and I got the impression that the core is trying to stick to ES3 (no Array.prototype.map, .filter, or the like.) And I don’t think there are ES3-compatible techniques for this.

Here’s one approach:

const o = {
  foo: 1,
  bar: 2,
  get baz() {
    console.log('calculating baz'); 
    Object.defineProperty(this, 'baz', {value: this.foo + this.bar, writeable: false});
    return this.baz;
  },
}

console.log(o.foo) //=> 1
console.log(o.bar) //=> 2
console.log(o.baz) //~> calculating baz //=> 3
console.log(o.foo) //=> 1
console.log(o.bar) //=> 2
console.log(o.baz) //=> 3

o.baz = 42         //*> throws "Cannot assign to read only property 'baz'"

Of course it it doesn’t have to look like property access, there are many options.

I have considered whether we might do this for all enumerable properties of the event object, as we often get requests to add variables for specific properties that we do not already support.