setAttribute For Nested Array in Wordpress Block Plugin Not Updating

admin2025-05-31  0

I am new to this area. I am just testing and working with the syntax to learn while slowly progressing to a functional block plugin. I have started this test project from one of the templates provided by the Wordpress Block Plugin beginner guide.

I have an array nested inside of another attribute array that I want to dynamically update.

I am creating a new array of the attribute to update then attempting to set the attribute but it is not updating.

I am not sure if its how my block.json is set or other syntax. Below is my block.json

{
"$schema": ".json",
"apiVersion": 3,
"name": "create-block/copyright-date-block",
"version": "0.1.0",
"title": "Copyright Date Block",
"category": "widgets",
"description": "My new description here...",
"example": {},
"attributes": {
    "rowCount": {
        "type": "number",
        "default": 0
    },
    "content": {
        "type": "array",
        "source": "query",
        "default": [],
        "query": {
            "cells": {
                "type": "array",
                "default": [],
                "source": "query",
                "query": {
                    "text": {
                        "type": "string",
                        "source":"html"
                    }
                }
            }
        }
    }
},
"supports": {
  "color": {
    "background": true,
    "text": true
    },
    "html": true,
    "typography": {
        "fontSize": true
    }
},
"textdomain": "copyright-date-block",
"editorScript": "file:./index.js",
"render": "file:./render.php",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css",
"viewScript": "file:./view.js"
  }

Below is my edit.js. In the function to update the content attribute, I have a console readout to validate the array is correct. The console reads perfectly fine. The issue is the content attribute doesn't update in the Wordpress database.

import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import './editor.scss';
import { InspectorControls, RichText } from '@wordpress/block-editor';
import { PanelBody, TextControl } from '@wordpress/components';
import { __experimentalNumberControl as NumberControl } from '@wordpress/components';
export default function Edit( { attributes, setAttributes } ) {

const { rowCount, content } = attributes;
const blockProps = useBlockProps();

function updateArray(arr, attributes){

    var test = attributes.content;
    var cells = ["one", "two"];
    test.push({cells});
    setAttributes({rowCount : arr});
    setAttributes({content : test});
    console.log(attributes.content[0]['cells'][0]);
}

function updateText(idx, index, text, attributes){
    {blockProps}
    //console.log(index + " = " + text);
    var oldArr = attributes.content;        
    oldArr[index][idx] = text;
    setAttributes( { content: oldArr });
}

return (
    <>
        <InspectorControls>
            <PanelBody title={ __( 'Settings', 'copyright-date-block' ) }>
                <NumberControl
                    __next40pxDefaultSize
                    spinControls='native'
                    label = { __('Configure row count')}
                    isShiftStepEnabled={ true }
                    onChange={ ( value ) =>
                        updateArray(value, attributes) }
                    shiftStep={ 1 }
                    value={ parseInt(rowCount) }
                />
            </PanelBody>
        </InspectorControls>
        
        <div { ...blockProps }>
                
                    { content.map((item, index) => {
                            return (
                                item['cells'].map((innerContent, idx) => {
                                    return (
                                            <RichText
                                                className= { "blah_" + idx }
                                                tagName="p"
                                                value={ innerContent + " - " + idx + " - " + index }
                                                allowedFormats={ [ 'core/bold', 'core/italic' ] } 
                                                onChange={ ( value ) => updateText(idx, index, value, attributes) } 
                                                placeholder={ __( '?...' ) } 
                                            />
                                            
                                            )   
                                        })
                                )
                        })
                    }
                    
                
        </div>
        
    </>
    
);
}

No matter how different I change the setAttributes line for the content attribute, it don't update in the database. Only the rowCount attribute updates.

Below is what is in the Wordpress database for post content while testing.

Ex. if I update the line incremented 4 times to update the rowCount, the rowCount attribute updates properly. Just not the content attribute.

<!-- wp:create-block/copyright-date-block {"rowCount":"4"} /-->

As stated before, I am attempting dynamic rendering using render.php that just echos a var_dump of $content attribute for now until I get this to work.

Any help would be appreciated.

I am new to this area. I am just testing and working with the syntax to learn while slowly progressing to a functional block plugin. I have started this test project from one of the templates provided by the Wordpress Block Plugin beginner guide.

I have an array nested inside of another attribute array that I want to dynamically update.

I am creating a new array of the attribute to update then attempting to set the attribute but it is not updating.

I am not sure if its how my block.json is set or other syntax. Below is my block.json

{
"$schema": "https://schemas.wp/trunk/block.json",
"apiVersion": 3,
"name": "create-block/copyright-date-block",
"version": "0.1.0",
"title": "Copyright Date Block",
"category": "widgets",
"description": "My new description here...",
"example": {},
"attributes": {
    "rowCount": {
        "type": "number",
        "default": 0
    },
    "content": {
        "type": "array",
        "source": "query",
        "default": [],
        "query": {
            "cells": {
                "type": "array",
                "default": [],
                "source": "query",
                "query": {
                    "text": {
                        "type": "string",
                        "source":"html"
                    }
                }
            }
        }
    }
},
"supports": {
  "color": {
    "background": true,
    "text": true
    },
    "html": true,
    "typography": {
        "fontSize": true
    }
},
"textdomain": "copyright-date-block",
"editorScript": "file:./index.js",
"render": "file:./render.php",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css",
"viewScript": "file:./view.js"
  }

Below is my edit.js. In the function to update the content attribute, I have a console readout to validate the array is correct. The console reads perfectly fine. The issue is the content attribute doesn't update in the Wordpress database.

import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import './editor.scss';
import { InspectorControls, RichText } from '@wordpress/block-editor';
import { PanelBody, TextControl } from '@wordpress/components';
import { __experimentalNumberControl as NumberControl } from '@wordpress/components';
export default function Edit( { attributes, setAttributes } ) {

const { rowCount, content } = attributes;
const blockProps = useBlockProps();

function updateArray(arr, attributes){

    var test = attributes.content;
    var cells = ["one", "two"];
    test.push({cells});
    setAttributes({rowCount : arr});
    setAttributes({content : test});
    console.log(attributes.content[0]['cells'][0]);
}

function updateText(idx, index, text, attributes){
    {blockProps}
    //console.log(index + " = " + text);
    var oldArr = attributes.content;        
    oldArr[index][idx] = text;
    setAttributes( { content: oldArr });
}

return (
    <>
        <InspectorControls>
            <PanelBody title={ __( 'Settings', 'copyright-date-block' ) }>
                <NumberControl
                    __next40pxDefaultSize
                    spinControls='native'
                    label = { __('Configure row count')}
                    isShiftStepEnabled={ true }
                    onChange={ ( value ) =>
                        updateArray(value, attributes) }
                    shiftStep={ 1 }
                    value={ parseInt(rowCount) }
                />
            </PanelBody>
        </InspectorControls>
        
        <div { ...blockProps }>
                
                    { content.map((item, index) => {
                            return (
                                item['cells'].map((innerContent, idx) => {
                                    return (
                                            <RichText
                                                className= { "blah_" + idx }
                                                tagName="p"
                                                value={ innerContent + " - " + idx + " - " + index }
                                                allowedFormats={ [ 'core/bold', 'core/italic' ] } 
                                                onChange={ ( value ) => updateText(idx, index, value, attributes) } 
                                                placeholder={ __( '?...' ) } 
                                            />
                                            
                                            )   
                                        })
                                )
                        })
                    }
                    
                
        </div>
        
    </>
    
);
}

No matter how different I change the setAttributes line for the content attribute, it don't update in the database. Only the rowCount attribute updates.

Below is what is in the Wordpress database for post content while testing.

Ex. if I update the line incremented 4 times to update the rowCount, the rowCount attribute updates properly. Just not the content attribute.

<!-- wp:create-block/copyright-date-block {"rowCount":"4"} /-->

As stated before, I am attempting dynamic rendering using render.php that just echos a var_dump of $content attribute for now until I get this to work.

Any help would be appreciated.

Share Improve this question asked May 6 at 8:40 Russell SjoblomRussell Sjoblom 111 bronze badge 0
Add a comment  | 

3 Answers 3

Reset to default 1

Thank you for everyones support but I figured out my wrong doing. I needed to look back at the Wordpress Block Editor Handbook. I needed to remove the "source":"query" from the top content attribute so the contents data would go into the blocks comment delimiter with rowCount.

Below is what I needed for it to work.

    "content": {
        "type": "array",
        "default": [],
        "query": {
            "cells": {
                "type": "array",
                "default": [],
                "source": "query",
                "query": {
                    "text": {
                        "type": "string",
                        "source": "text"

                    }
                }
            }
        }
    }

Merge both updates in one setAttributes call

setAttributes({
    rowCount: arr,
    content: test
});

The setAttributes should work with multiple lines. Just make sure to adjust the data handling in your updateArray function accordingly, so that the contents are correctly added.

Here's a little tip to help you out.

An example (not tested):

function updateArray(arr, attributes) {
        const cells = ['one', 'two'];

        // Safely create a new array from existing content or initialize as empty
        const oldContent = Array.isArray(attributes.content)
            ? [...attributes.content]
            : [];

        // Add a new row
        oldContent.push({ cells });

        // Update the attributes
        setAttributes({ rowCount: arr, content: oldContent });

        // Optional: log safely
        if (oldContent[0] && Array.isArray(oldContent[0].cells)) {
            console.log(oldContent[0].cells[0]);
        }
    }
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1748634154a313676.html

最新回复(0)