Model IDs not included in has-many toArray() queries

Hi there,

I have a webhook that is triggering a CloudCode task when a form is submitted. That form object will be sent to the CloudCode task, where I am compiling all of the object’s fields, belongs-to and has-many relationships into one custom JS object before POSTing it to an external system. For the has-many relationships, I am calling object..toArray() and noticing that, for each object in the array of objects, the ID is missing. Is this the expected behavior of toArray(), or is this a bug?

The array of objects looks like the following:
“objects”: [
{
“field1”: …,
“field2”: …,
},
{
“field1”: …,
“field2”: …,
}
]

Should the ID for each object be included along with the fields?

Thank you!

1 Like

The underlying database object hides this, but the value is still accessible.

The following CloudCode snippet shows an example where you can create a copy of the object and expose the ID value:

export async function run(this: TaskContext) {
    const user = await DB.user.first();
    const warehouses = await user.warehouses.toArray();
    const copyOf = [];

    for(let warehouse of warehouses) {
        // Use the spread operator (...) to copy visible fields to a new object
        // See for more information: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
        const newObject = { 
            id: warehouse.id,
            ...warehouse
        };
        copyOf.push(newObject);
    }

    console.log(JSON.stringify(copyOf, null, 2));
}

Thanks for the response!

I am having trouble getting the spread operator to work. I keep getting an error message that says “index.js: Unexpected token (220:16)”.

Any advice about how to get around this? I tried installing multiple babel plugins related to the spread operator, but I got the same error message regardless of the package.

I tested this solution with a TypeScript CloudCode task. Please remove all babel packages from your task, this is going to cause issues with your CloudCode Task.

Here is where you can select the TypeScript template when creating a new CloudCode task.

Another option is to use Object.assign, e.g.

export async function run() {
    const user = await DB.user.first();
    const warehouses = await user.warehouses.toArray();
    const copyOf = [];

    for(let warehouse of warehouses) {
        // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
        const newObject = Object.assign({ id: warehouse.id }, warehouse);
        copyOf.push(newObject);
    }

    console.log(JSON.stringify(copyOf, null, 2));
}