Save the date! Join us on October 16 for our Product Ops launch event. Register here.
Jan 05, 2020 01:37 PM
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 await
ing the Promise – am I doing something wrong with the async function here?
Thank you in advance for helping me improve my understanding of JavaScript!
Solved! Go to Solution.
Jan 05, 2020 01:54 PM
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'}]
});
});
Jan 05, 2020 01:54 PM
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'}]
});
});
Jan 05, 2020 02:15 PM
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: