Search code examples
osascriptjavascript-automation

How to define a persistent property in JXA


In AppleScript I would write

property foo: "value"

and the value would be saved between runs. How can I do this in Javascript for Automation?


Solution

  • JavaScript for Automation doesn't have a direct parallel for the persistent property (and global value) mechanism of AS, but it does have JSON.stringify() and JSON.parse(), which work well for simple serialisation and retrieval of state.

    Perhaps something broadly like:

    (function () {
        'use strict';
    
        var a = Application.currentApplication(),
            sa = (a.includeStandardAdditions = true, a),
            strPath = sa.pathTo('desktop').toString() + '/persist.json';
    
        // INITIALISE WITH RECOVERED VALUE || DEFAULT
        var jsonPersist = $.NSString.stringWithContentsOfFile(strPath).js || null,
            persistent = jsonPersist && JSON.parse(jsonPersist) || {
                name: 'perfume',
                value: 'vanilla'
            };
        /*********************************************************/
    
        // ... MAIN CODE ...
    
        // recovered or default value
        sa.displayNotification(persistent.value);
    
        // mutated value
        persistent.value = "Five Spice"
    
        /*********************************************************/
    
        // WRAP UP - SERIALISE TO JSON FOR NEXT SESSION
        return $.NSString.alloc.initWithUTF8String(
            JSON.stringify(persistent)
        ).writeToFileAtomically(strPath, true);
    
    })();
    

    (A fuller example here: https://github.com/dtinth/JXA-Cookbook/wiki/Examples#properties-which-persist-between-script-runs )

    Or, for simple key-value pairs rather than arbitrary data structures, see: https://stackoverflow.com/a/31902220/1800086 on JXA support for writing and reading .plist