Help

Upcoming database upgrades. to improve our reliability at 03:30 UTC on Feb. 25 / 7:30pm PT on Feb. 24. Some users may briefly experience slow load times or error messages. Learn more here

Creating records

Topic Labels: Custom Extensions
Solved
Jump to Solution
1108 2
cancel
Showing results for 
Search instead for 
Did you mean: 

My JS needs some help :frowning:

I’m trying to create a new record in one table for each of the records I pulled out of a view in another table. I’ve tried using

people.map(person => {}),
people.forEach(person => {}),
and
for (const person of people) {},

but I get the same error in all 3 cases:

Error: <root> must be an array
    at Mutations._assertMutationIsValid (https://localhost:9000/__runFrame/bundle.js:4139:53)
    at _callee$ (https://localhost:9000/__runFrame/bundle.js:3852:21)
    at tryCatch (https://localhost:9000/__runFrame/bundle.js:75258:40)
    at Generator.invoke [as _invoke] (https://localhost:9000/__runFrame/bundle.js:75484:22)
    at Generator.prototype.<computed> [as next] (https://localhost:9000/__runFrame/bundle.js:75310:21)
    at tryCatch (https://localhost:9000/__runFrame/bundle.js:75258:40)
    at invoke (https://localhost:9000/__runFrame/bundle.js:75348:20)
    at https://localhost:9000/__runFrame/bundle.js:75383:11
    at new Promise (<anonymous>)
    at callInvokeWithMethodAndArg (https://localhost:9000/__runFrame/bundle.js:75382:16)

Here’s the relevant part of my block code:

function PeopleHolidaysBlock() {
    const base = useBase();

    ...

    const peopleTable = base.getTableByIdIfExists(Globals.PEOPLE_TABLE_ID);
    const christmasView = peopleTable ? peopleTable.getViewByIdIfExists(Globals.PEOPLE_CHRISTMAS_VIEW_ID) : null;
    const queryResult = christmasView ? christmasView.selectRecords() : null;
    const people = useRecords(queryResult);

    const peopleHolidaysTable = base.getTableByIdIfExists(Globals.PEOPLE_HOLIDAY_TABLE_ID);

    return (
        <div>
           ...
            <p>{people.length}</p>
            { notYetRunForCurrentYear && // only show button if not yet run for current year
                <Button
                    onClick={() => { generateChristmasRecords() }}
                    variant="primary"
                >
                    Generate {new Date().getFullYear()} Christmas Records
                </Button>
            }
        </div>
    );

    function notYetRunForCurrentYear() {
        // placeholder...
        return true;
    }

    function generateChristmasRecords() {
        // create a People-Holiday::Christmas record for each person in the People table
        people.map(person => {
            peopleHolidaysTable.createRecordAsync({
                'Person' : `${person.id}`,
                'Holiday' : 'Christmas'
            });
        });

        alert(`${people.length} people`);
    }
}

I’m not understanding what the error message is getting at. people.length both in the return <p></p> and in the alert is returning the expected value, so I’m pretty sure I’ve got a valid array.

I’m not concerned with guaranteeing persistence at this point, so I thought I could skip awaiting the Promise – am I doing something wrong with the async function here?

Thank you in advance for helping me improve my understanding of JavaScript!

1 Solution

Accepted Solutions

Well, there’s a classic case of :duck: debugging – in writing that out, it occurred to me that the fields I named in the createRecordAsync() function might be expecting objects or arrays as values since they are linked record fields, and that was indeed the cause of the error… it had nothing to do with my people array!

I’ll go ahead and leave this here for reference in case it’s helpful to others.

Here’s the final working .map function:

// create a People-Holiday::Christmas record for each person in the People table
people.map(person => {
    peopleHolidaysTable.createRecordAsync({
        'Person' : [{id: `${person.id}`}],
        'Holiday' : [{id: 'reclZYRpInJiev0ce'}]
    });
}); 

See Solution in Thread

2 Replies 2

Well, there’s a classic case of :duck: debugging – in writing that out, it occurred to me that the fields I named in the createRecordAsync() function might be expecting objects or arrays as values since they are linked record fields, and that was indeed the cause of the error… it had nothing to do with my people array!

I’ll go ahead and leave this here for reference in case it’s helpful to others.

Here’s the final working .map function:

// create a People-Holiday::Christmas record for each person in the People table
people.map(person => {
    peopleHolidaysTable.createRecordAsync({
        'Person' : [{id: `${person.id}`}],
        'Holiday' : [{id: 'reclZYRpInJiev0ce'}]
    });
}); 

Something worth noting as well is that where in the regular api you use an array of record id strings to set a linked record field:

fields: {
  linkedRecordField: ['id1', 'id2']
}

In the blocks api, you need to use an array of objects with ids:

fields: {
  linkedRecordField: [{id: 'id1'}, {id: 'id2'}] 
}

Found that out the hard way, after spending too much time trying to figure out why something that works with the regular api doesn’t work with the block api :slightly_smiling_face: