JXA — Getting the context of a task

I use contexts to identify where a task is in its progression to completion: so: “research”, “writing”, “editing”, etc.

For use in a script, I want to be able to use JXA to find the context of the selected task, but there are easy ways to get a list of tasks when you have the context, but not the other way around. So far I have this function, which takes a task id and returns the name of the context:

function selected_task_context(task_id) {
var contexts = omni.document()[0].flattenedContexts()
for (i = 0; i < contexts.length; i++){
	var context = contexts[i]
	for (c = 0; c < context.tasks().length; c++) {
		var task = context.tasks()[c]
		if ((task.id()) == task_id){
			return context.name()

As you can see, it iterates through all the tasks in every context until it finds the one that matches the task supplied in the parameter. This “works” but it doesn’t seem an elegant solution, so I was wondering if anyone had a better idea.

Ugh! Why not simply find the task within the document whose name is equal to the input, then get the context of the found task? Why iterate through all contexts???


Or, you could get the context name of the selected task.
I’m not very familiar with JXA but this is a starting point. Does it help you?


//This function gets context name for the first selected task

function getContextName() {
var of = Application('OmniFocus'), 
ofDoc = of.defaultDocument,
ofContent = ofDoc.documentWindows.at(0).content,
ofSelection = ofContent.selectedTrees.at(0).value();

return ofSelection.context.name();

That’s perfect. Thank you.

@DrJJWMac, perhaps not a reasonable excuse, but I’m completely new to JXA and Apple automation. I’m finding it quite difficult to figure out from the OmniFocus dictionary what is a property of what in the object hierarchy.

So far as I could see from the dictionary, a Context has a list of tasks as a property, but a Task doesn’t have its context as a property. In fact, although @unlocked2412’s code works perfectly well, I have no clue how they got to that given the dictionary as a starting point.

I was more amazed by the brute-force programming effort you undertook, basically to set a finishing nail with a jack hammer.


The Task class defines a context property which, in turn, is of the Context class.

I am not familiar with JXA but I did a lot of OmniFocus scripts in Applescript. So, I understand OmniFocus object model and translated what I know into JXA language.
As you say, it’s difficult to figure out from the dictionary the object hierarchy. It takes a lot of time and patience. But, it’s possible.
If you need anything else, tell me.

@unlocked2412 Yes, after looking more carefully in light of your example I found that. I should spend more time with the dictionary before making assumptions about what’s in there.

That’s why I asked the question. I didn’t believe it could be the proper way to do it. I made an incorrect assumption about what was possible from a cursory study of the dictionary.

Thanks for all your help.

Ah ha! I see. Not realizing that context can be extracted directly from a task’s name, you thought that you had to go the long way around to pull the task name out of a context-categorized list of tasks. Hence the iteration loop. That was the jack hammer … pounding away incessantly.

As I said. Ugh.