Inconsistent Order of Results With getData

Hi everyone, looking for some advice. I’ve been seeing weird to me behavior when using getData over the last few days. In the past, I used the method of “await getData” for each separate variable I want to get. I started requesting multiple variables at a time in an effort to make my code ‘better’ and reduce runtime, but variables now seem to appear in varying orders.

Steps I took to produce this result:

  • An action runs the below analysis each time “command” is updated

  • I am using the following payload within the device emulator to trigger the analysis with a valid scope

      [
        {
          "variable": "identifier",
          "value": "123456789"
        },
        {
          "variable": "command",
          "value": "abcde_command_12345"
        }
      ]
    
  • I am using the following script as the analysis

    const { Analysis, Device, Utils, Account } = require("@tago-io/sdk");
    const axios = require("axios");
    async function getToHTTP(context, scope) {
    //Create the environment
    const env_vars = Utils.envToJson(context.environment);
    //Make sure there is an account token
    if (!env_vars.account_token){
      throw 'Missing account_token environment var';
    }
    //Create an account object
    const account = new Account({ token: env_vars.account_token });
    
    //Get the device id, device token, and create the device
    const {origin} = scope[0]
    const device_token = await Utils.getTokenByName(account, origin);
    const device = new Device({ token: device_token })
    
    //Use getData to retrieve both the identifier and command together
    const command_options = await device.getData(
      [
        {
          query: "last_value",
          variable: "identifier"
        },
        {
          query: "last_value",
          variable: "command"
        }
      ]
      );
    
      //Use getData to retrieve the identifier alone
      const identifier = await device.getData(
        {
          query: "last_value",
          variable: "identifier"
        }
      );
      //Use getData to retrieve the command alone
      const command = await device.getData(
        {
          query: "last_value",
          variable: "command"
        }
      );
    
      //Output the resulting data sets to compare ordering
      context.log("Together: " + command_options[0].value + " " + command_options[1].value);
      context.log("Separate: " + identifier[0].value + " " + command[0].value);
    
      //Cut the analysis short for display
      return;
    

Expected output if I run the emulator:
Separate: 123456789 abcde_command_12345
Together: 123456789 abcde_command_12345

Actual output if I run the emulator 3 times:
[2021-02-08 20:32:10] Separate: 123456789 abcde_command_12345
[2021-02-08 20:31:18] Together: 123456789 abcde_command_12345

[2021-02-08 20:40:55] Separate: 123456789 abcde_command_12345
[2021-02-08 20:40:55] Together: abcde_command_12345 123456789

[2021-02-08 20:41:33] Together: abcde_command_12345 123456789
[2021-02-08 20:41:33] Separate: 123456789 abcde_command_12345

Change the payload to remove the identifier. Since the analysis is triggered by the command and I get the “last_value”, the identifier should be retrieved the same as before:

[
  {
    "variable": "command",
    "value": "abcde_command_12345"
  }
]

Expected:
Separate: 123456789 abcde_command_12345
Together: 123456789 abcde_command_12345

3 emulator runs::
[2021-02-08 20:42:19] Separate: 123456789 abcde_command_12345
[2021-02-08 20:42:19] Together: abcde_command_12345 123456789

[2021-02-08 20:42:53] Together: abcde_command_12345 abcde_command_12345
[2021-02-08 20:42:53] Separate: 123456789 abcde_command_12345

[2021-02-08 20:42:55] Separate: 123456789 abcde_command_12345
[2021-02-08 20:42:55] Together: abcde_command_12345 abcde_command_12345

The value of the identifier is somehow overwritten by the command value; but only within that specific getData result. Am I doing something wrong with my implementation of getData? Is getting multiple variables with a single getData call not officially supported? Any help would be appreciated, this has been annoying me and I’d rather not go through my latest set of scripts to separate all getData calls unless absolutely necessary. Thank you!

Hi Andreas,
The result from the getData can not respect the order of the variables that you sent. It also changes the order if a variable doesn’t have any value.

In order to get the correct variable without using it’s position in the array, you can use the following code:

  const data= await device.getData(
    {
      query: "last_value",
      variables: ["identifier", "command"]
    }
  );

const identifier = data.find((x) => x.variable === "identifier");
const command = data.find((x) => x.variable === "command");

now you can use as this:

  //Output the resulting data sets to compare ordering
  context.log("Together: " + command.value + " " + command.value);
  context.log("Separate: " + identifier.value + " " + identifier.value);