This tutorial creates a JavaScript transform that automatically responds to a published message by looking up a record in another table and changing its state. It uses FairCom's built-in runJsonAction(request) function to perform these tasks.
Using the techniques in this tutorial, you can write JavaScript code to perform any type of JSON action in response to MQTT messages, inserted records, and collected data.
Run the tutorial
Use the API Explorer in FairCom's Data Explorer web application to run the following commands.

- Create the machine table to track the state of machines.
{ "api": "db", "action": "createTable", "params": { "tableName": "machine", "fields": [ { "name": "name", "type": "varchar", "length": 50 }, { "name": "status", "type": "varchar", "length": 16 } ] }, "authToken": "replaceWithAuthTokenFromCreateSession" }
- Insert records into the machine table.
{ "api": "db", "action": "insertRecords", "params": { "tableName": "machine", "dataFormat": "objects", "sourceData": [ { "name": "machine1", "status": "normal" }, { "name": "machine2", "status": "off" }, { "name": "machine3", "status": "normal" } ] }, "authToken": "replaceWithAuthTokenFromCreateSession" }
- Create the code package that the JavaScript transform will run. It is named "changeMachineState".
{ "api": "admin", "action": "createCodePackage", "params": { "codeName": "changeMachineState", "codeLanguage": "javascript", "codeType": "integrationTableTransform", "codeStatus": "active", "description": "1. Lookup for the machine by ID.\n2. If new status is different from the machine record, update it.\n3. Populate the machine_name and machine_status fields.", "code": "//language=JavaScript\n//1. Lookup for the machine by ID.\n//2. If new status is different from the machine record, update it.\n//3. Populate the machine_name and machine_status fields.\n\n\n// Lookup the machine register by the ID in the payload\nconst machineId = record.source_payload.machineID;\nconst newStatus = record.source_payload.newStatus;\nlet machine = getMachineByID(machineId);\n\n\n// If machine status from the payload is different, update the machine table\nif ( machine.status !== newStatus )\n updateMachineStatus(machineId, newStatus);\n\n\n// Set the machine_name and machine_status fields\nrecord.machine_name = machine.name;\nrecord.machine_status = newStatus;\n\n\n//==================================================================\n// Function to retrieve the machine record by ID through JSON Action\nfunction getMachineByID(machineID)\n{\n const request =\n {\n \"api\": \"db\",\n \"action\": \"getRecordsByIds\",\n \"params\":\n {\n \"tableName\": \"machine\",\n \"ids\": [machineID]\n }\n };\n\n\n const response = runJsonAction(request);\n\n\n if (response.errorCode !== 0)\n throw \"ERROR: getMachineByID() cannot find machine with ID \" + machineId + \".\" +\n \" errorCode: \" + response.errorCode +\n \" errorMessage: \" + response.errorMessage ;\n\n\n return response.result.data[0];\n}\n\n\n//==================================================================\n// Function to update the machine status by ID through JSON Action\nfunction updateMachineStatus(machineID, newMachineStatus)\n{\n const request =\n {\n \"api\": \"db\",\n \"action\": \"updateRecords\",\n \"params\": {\n \"tableName\": \"machine\",\n \"ignoreChangeIdProtection\": true,\n \"sourceData\": [\n {\n \"id\": machineID,\n \"status\": newMachineStatus\n }\n ]\n }\n };\n\n\n const response = runJsonAction(request);\n\n\n if (response.errorCode !== 0)\n throw \"ERROR: updateMachineStatus() cannot update Machine with ID \" + machineId + \".\" +\n \" errorCode: \" + response.errorCode +\n \" errorMessage: \" + response.errorMessage ;\n}" }, "authToken": "replaceWithAuthTokenFromCreateSession" }- The code embedded in the code package's "code" property looks like the following:
//1. Lookup for the machine by ID. //2. If new status is different from the machine record, update it. //3. Populate the machine_name and machine_status fields. // Lookup the machine register by the ID in the payload const machineId = record.source_payload.machineID; const newStatus = record.source_payload.newStatus; let machine = getMachineByID(machineId); // If machine status from the payload is different, update the machine table if ( machine.status !== newStatus ) updateMachineStatus(machineId, newStatus); // Set the machine_name and machine_status fields record.machine_name = machine.name; record.machine_status = newStatus; //================================================================== // Function to retrieve the machine record by ID through JSON Action function getMachineByID(machineID) { const request = { "api": "db", "action": "getRecordsByIds", "params": { "tableName": "machine", "ids": [machineID] } }; const response = runJsonAction(request); if (response.errorCode !== 0) throw "ERROR: getMachineByID() cannot find machine with ID " + machineId + "." + " errorCode: " + response.errorCode + " errorMessage: " + response.errorMessage ; return response.result.data[0]; } //================================================================== // Function to update the machine status by ID through JSON Action function updateMachineStatus(machineID, newMachineStatus) { const request = { "api": "db", "action": "updateRecords", "params": { "tableName": "machine", "ignoreChangeIdProtection": true, "sourceData": [ { "id": machineID, "status": newMachineStatus } ] } }; const response = runJsonAction(request); if (response.errorCode !== 0) throw "ERROR: updateMachineStatus() cannot update Machine with ID " + machineId + "." + " errorCode: " + response.errorCode + " errorMessage: " + response.errorMessage ; }- In JetBrains IDEs, you can paste the previous code into an empty string "" in a JSON file and the IDE will automatically escape the code to work in the string. There are also online stringify and unstringify tools that do the same.
- "configureTopic".
{ "api": "mq", "action": "configureTopic", "params": { "topic": "controlMachine", "tableName": "controlMachine" }, "authToken": "replaceWithAuthTokenFromCreateSession" }
- Modify integration table to add extra fields and transform steps:
-
You have completed the tutorial and can run the demo to publish messages to the "controlMachine" topic that automatically update the state of machines in the machine table.{ "api": "hub", "action": "alterIntegrationTable", "params": { "tableName": "controlMachine", "addFields": [ { "name": "machine_name", "type": "varchar", "length": 50 }, { "name": "machine_status", "type": "varchar", "length": 16 } ], "transformSteps": [ { "transformStepMethod": "javascript", "transformStepService": "v8TransformService", "codeName": "changeMachineState", "ownerName": "admin", "databaseName": "faircom" } ] }, "authToken": "replaceWithAuthTokenFromCreateSession" }
-
Demo
You can preview the results of the tutorial by looking at the screenshots now. After you have finished the tutorial, you can run this demo and publish messages to the controlMachine topic to change the state of machines in the machine table.
- Use MQ Explorer to publish the following JSON message to the controlMachine topic. The purpose of the message is to update the status of machine 3 to the "ready" state.
{ "machineID": 3, "newStatus": "ready" }
- Use Edge Explorer to view the record in the mqtt_msg_controlmachine table. You can see that the record's source_payload field contains the published message. You can also see two columns in the table, machine_name and machine_status, which contain the machine's name and status. The JavaScript transform populated these fields.
- Use Data Explorer to view the machine table and verify its record matches the new status of "ready" as requested in the MQTT message. The JavaScript transform used FairCom's built-in runJsonAction(request) function to run JSON actions to look up the record with an ID of 3 and update its status to "ready".
- Use MQ Explorer to publish a new JSON message to the controlMachine topic to update machine 3 to the "offline" state.
{ "machineID": 3, "newStatus": "offline" }
- Use Edge Explorer to refresh the records to view the new record in the mqtt_msg_controlmachine table that contains the published message. Notice the machine_status field now has a state of "offline".
- Use Data Explorer to refresh the records in the machine table and verify that its record matches the new status of "offline".



