I'm trying to dynamically create and change values of components with mapping an array. Everything works fine initially (when I map through default values) until I get to setPadding function which is supposed to set an attribiute. Then my array is changed into object making the second mapping to throw an error - react-dom.min.js?ver=16.9.0:103 TypeError: attributes.padding.map is not a function
. Here is the code:
The attribute:
padding: {
type: 'array',
default: [
{ name: 'top',
image: `${ url }images/padding-top.svg`,
v: 10,
},
{
name: 'bottom',
image: `${ url }images/padding-bottom.svg`,
v: 10,
},
],
},
The component render (note attribiutes.padding
being mapped - this works fine with default values):
<PanelBody
title="Test"
initialOpen={ true }
>
{ attributes.padding.map( ( attr ) => (
<div className="component-row-wrapper margin-padding">
<PanelRow>
<RangeControl
label={
<img src={ attr.image } alt="" />
}
value={ attr.v }
onChange={ ( value ) => setPadding( attr.name, value ) }
min={ 0 }
max={ 300 }
/>
</PanelRow>
</div>
), ) }
</PanelBody>
And finally setPadding
function (with console.log
before the function itself - this is placed somewhere between edit( props )
and component render):
console.log( attributes.padding ); // initially it works fine, after setPadding it logs object instead of array.
const setPadding = ( name, value ) => {
const paddingAttr = attributes.padding;
{paddingAttr.map( r => {
if ( name === r.name ) {
r.v = value;
}
} );}
console.log( paddingAttr ); // works fine, being displayed as array every time!
props.setAttributes( {
padding: { paddingAttr }, // saves 'padding' attribute as object 'paddingAttr: Array(2)...' instead of array ??
} );
};
What am I doing wrong here?
Thank you very much!
Where you call props.setAttributes
, the reason the attribute is an object is because you are creating an object! You need the following:
props.setAttributes( {
padding: paddingAttr
} );
Read more about property shorthand notation on MDN.
Additionally, as I said, you'll need to fix that call to Array#map
. Change it to the following:
paddingAttr = paddingAttr.map( r => {
if ( name === r.name ) {
r.v = value;
}
return r;
} );