Hereās an updated example thatās hopefully clearerā¦? Let me know if I can explain anything.
Itāll be in the official docs once CI/CD passes, but in the meantime, here it is:
The updated example
import {buildClient} from '@datocms/cma-client-node';
async function run() {
// Make sure the API token has access to the CMA, and is stored securely
const client = buildClient({apiToken: process.env.DATOCMS_API_TOKEN});
// These define what to update
const recordId = "A4gkL_8pTZmcyJ-IlIEd2w"; // The record's unique ID
const fieldWithBlocks = 'modular_content_field' // Which record field are the blocks in?
const blockId = 'ToBApjdYQaCgeFJxp_ty0A'; // ID of the block we want to update ("Example block #1")
const blockFieldsToUpdate = { // Inside the block, what are we updating?
title: 'Example block #1 (Updated title)' // Update the title
}
// Get the current record
const currentRecord = await client.items.find(recordId, {
nested: true // Also fetch the content of nested blocks, not just their IDs
});
console.log('currentRecord before update', JSON.stringify(currentRecord[fieldWithBlocks], null, 2))
// Build the update before sending it
const currentBlock = currentRecord[fieldWithBlocks].find(block => block.id === blockId) // The block's existing content
const updatedBlock = {
...currentBlock, // Keep its existing metadata
attributes: {
...currentBlock.attributes, // Keep existing attributes that we didn't update
...blockFieldsToUpdate // Inject updated fields
}
}
const updatedFieldWithBlocks = currentRecord[fieldWithBlocks].map(block => // Map through existing blocks so we keep their ordering
block.id === updatedBlock.id
? updatedBlock // If it's the block we want to update, inject the updated data
: block.id // Otherwise, just provide the old block's ID and the API will know to keep it unchanged
)
// Perform the update by actually sending what we built to the API
const updatedRecord = await client.items.update(recordId, {
[fieldWithBlocks]: updatedFieldWithBlocks // The record field to update
// We don't have to specify the other fields. The API will keep them the same.
})
console.log('Updated record field. By default we only return the block IDs.', updatedRecord[fieldWithBlocks])
// (Optional, only if you want to verify it manually) Make another request to fetch the updated nested blocks
const updatedRecordWithNestedBlocks = await client.items.find(recordId, {
nested: true // Also fetch the content of nested blocks, not just their IDs
});
console.log('Updated record field with nested blocks', updatedRecordWithNestedBlocks[fieldWithBlocks])
}
run();
Before the update
currentRecord before update [
{
"type": "item",
"attributes": {
"title": "Example block #1",
"nested_modular_content_field": [
{
"type": "item",
"attributes": {
"title": "Nested block inside example block #1",
"nested_modular_content_field": []
},
"relationships": {
"item_type": {
"data": {
"id": "cR-9e-65SNat84KEs5M22w",
"type": "item_type"
}
}
},
"id": "YByg71hHQzOxIow2P6eujg"
}
]
},
"relationships": {
"item_type": {
"data": {
"id": "cR-9e-65SNat84KEs5M22w",
"type": "item_type"
}
}
},
"id": "ToBApjdYQaCgeFJxp_ty0A"
},
{
"type": "item",
"attributes": {
"title": "Example block #2",
"nested_modular_content_field": []
},
"relationships": {
"item_type": {
"data": {
"id": "cR-9e-65SNat84KEs5M22w",
"type": "item_type"
}
}
},
"id": "YGrrPYrkSNaq-dBaP7aSaQ"
}
]
After the update
If you just log updatedRecord
, youāll get back only the block IDs:
Updated record field. By default we only return the block IDs. [ 'ToBApjdYQaCgeFJxp_ty0A', 'YGrrPYrkSNaq-dBaP7aSaQ' ]
You have to make another item.find()
request to see the updated blocks with their nested content:
Updated record field with nested blocks [
{
type: 'item',
attributes: {
title: 'Example block #1 (Updated title)',
nested_modular_content_field: [Array]
},
relationships: { item_type: [Object] },
id: 'ToBApjdYQaCgeFJxp_ty0A'
},
{
type: 'item',
attributes: { title: 'Example block #2', nested_modular_content_field: [] },
relationships: { item_type: [Object] },
id: 'YGrrPYrkSNaq-dBaP7aSaQ'
}
]
I hope that helps! Please still feel free to email us with your specific model/record details if youād like me to write a sample script for you.