OSC Reply/translate using JSON object array

Hi there!

Basically, I'm looking to make a custom module to act as a translator to take an incoming OSC message with an integer argument, looks up that integer as a key in a JSON array of objects, and then send out a reply OSC message with a string argument that is a "name" value contained in the looked up/found JSON object.

The JSON data looks something like this

[
  {
    "id": "Aatrox",
    "key": 266,
    "name": "Aatrox",
    "title": "the Darkin Blade"
  },
  {
    "id": "Ahri",
    "key": 103,
    "name": "Ahri",
    "title": "the Nine-Tailed Fox"
  },
  {
    "id": "Akali",
    "key": 84,
    "name": "Akali",
    "title": "the Rogue Assassin"
  },
  {
    "id": "Akshan",
    "key": 166,
    "name": "Akshan",
    "title": "the Rogue Sentinel"
  }
]

So for example, the incoming OSC message would be something like /ChampSelect/Slot1 : 84
I'd then want to translate that into a new OSC message, something like /Video/Layer : "Akali". This would be obtained by looking up the key integer 84 in the JSON array, and returning the "name" value.

I understand very basic JavaScript, and the example "Reply" script makes sense to me. But I'm still very much a beginner and I'm just not sure where to start in terms of having the script sift through and find a JSON object based on its key.

Would anyone be able to steer me in the right direction as to how I might go about doing this?

The full JSON array would contain 150-200 objects. As a bonus, it would be super cool if I could change/select the JSON file using the File widget within Open Stage Control. But that's not necessarily a requirement.

I really appreciate any guidance or direction anyone could give me! Thanks!

Here you go:

// load initial JSON data
// we assume the file always contains an array of objects
var my_data = loadJSON('./data.json')

module.exports = {

    oscInFilter: function(data) {

        var {host, port, address, args} = data

        if (address === '/ChampSelect/Slot1') {

            // find item in my_data with key === first argument of osc message
            var subdata = my_data.find(item=>item.key === args[0].value)

            if (subdata) {

                send('127.0.0.1', 5555, '/Video/Layer', subdata.id)

            } else {

                console.log(`No data found for ${address} ${args[0].value} `)

            }

            // return // uncomment to bypass original message if it doesn't need to reach any widget

        }

        return data

    },

    oscOutFilter:  function(data) {

        var {host, port, address, args} = data

        // assuming we have a file widget with this address
        // (and a target set so that it sends a message that we can catch here)
        if (address === '/load_json') {

            var path = args[0].value
            // update my_data with new file
            my_data = loadJSON(path)
            
            return // this message has no probably reason to be sent
        }

        return data

    }

}

Reference:

1 Like

Thank you so much!!! This is a perfect starting point, just needed someone to point the way. Much appreciated.