Skip to main content
Solved

Creating records


Forum|alt.badge.img+18

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!

Best answer by Jeremy_Oglesby

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'}]
    });
}); 
View original
Did this topic help you find an answer to your question?

2 replies

Forum|alt.badge.img+18
  • Author
  • Inspiring
  • 1691 replies
  • Answer
  • January 5, 2020

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'}]
    });
}); 

Forum|alt.badge.img+14

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:


Reply