2

`The Javascript Automation release note by Apple has an example for searching an array with arbitrary objectSpecifier.

firstTabsName = ObjectSpecifier.tabs[0].name
app.windows.whose({_match: [firstTabsName, 'Apple']})

However, the first lines throws an error. "TypeError: undefined is not an object (evaluating 'ObjectSpecifier.tabs') What am I doing wrong? Thank you for your help!`

jackjr300
  • 7,111
  • 2
  • 15
  • 25
jl303
  • 1,461
  • 15
  • 27

2 Answers2

4

The first line blows up at firstTabsName = ObjectSpecifier.tabs, which returns missing value. Nothing past that point can succeed.

The code you posted appears to be from the Apple Release Notes, which is missing an empty set of parens right after "ObjectSpecifier" and another set after the whose statement. When you add those parens, the constructor for ObjectSpecifier is called AND the final whose specifier is resolved to a list of matching windows. So, the corrected code is:

app = Application('Safari')
firstTabsName = ObjectSpecifier().tabs[0].name // added parens
app.windows.whose({_match: [firstTabsName, "Apple"]})() // added parens
// --> [Application("Safari").windows.byId(9016)]
Ron Reuter
  • 1,287
  • 1
  • 8
  • 14
  • Thanks! That's exactly what was missing. Is that possible to put a whose filter on a ObjectSpecifier? Something like ObjectSpecifier().checkboxes.whose({name:"find"})().value – jl303 Jul 12 '16 at 00:06
  • I don't think so. As of 10.11 you can only 1) Check whether an object is an object specifier, 2) Get the class of an object specifier, or 3)Build arbitrary object specifier chains for use in whose clauses. For your example, you don't need a whose clause, you can specify the object by name directly. For instance, to get the value of the persistentID property of the iTunes Library you would use: `Application("iTunes").sources.byName("Library").persistentID()`. Whose clauses are only needed when you need to filter a list and get back zero or more matches in another list for further processing. – Ron Reuter Jul 12 '16 at 01:24
  • Thank you so much. Here's my situation. I have a group (let's called group), containing another array of groups (let's call people, and each person contains an array of checkboxes (let's call checkbox). I need to get list of people who have a checkbox named "mute," and the checkbox mute must have value of 1. The tricky part is that the index of the mute checkbox always changes, so I can't do something like "ObjectSpecifier().checkboxes[0].value". Is that possible to achieve this using whose function without using for loop? Thank you again. – jl303 Jul 13 '16 at 00:41
  • @jl303 Your case is sufficiently complex that you are just going to have to try different solutions. The parameters sent to the whose({...}) in my code above can be more complex, including AND and OR combinations, but constructing such a statement may be error prone. You might get it to work, or it might be easier to just use loops. Good luck! If you solve it, please post the code for others to learn from. – Ron Reuter Jul 13 '16 at 21:44
  • Is there a way to build a filtering ObjectSpecifier using whose or byName? Something like: mute = ObjectSpecifier().checkboxes.byName("Mute")[0].value mutedPersons = people.whose({_match:[mute,"Selected"]}) Thanks! – jl303 Aug 15 '16 at 21:22
  • Just stumbled upon this answer. The double missing parenthesis in the docs is a real killer. I eventually figured out I needed one after ObjectSpecifier, but this answer made me aware of the one needed after the `whose` function. So annoying! – James Apr 11 '19 at 14:21
0
mute = ObjectSpecifier().checkboxes["Mute"].value
mutedPersons = people.whose({_match:[mute,"Selected"]}
jl303
  • 1,461
  • 15
  • 27