Your Problem is that the JSON is actually no JSON (replace = with :) and further the data isn't parsed automatically to an object array when you share it through the attributes of the component. I would use a generic function like getDataFromProperty
and outsource it in a different file that you can use it in all your web components. But lets keep it simple for now:
@Prop() cards: Array<object> = [];
private getDataFromProperty(toParse):any{
try(JSON.parse(toParse)){
return JSON.parse(toParse);
}catch(e){
//some different conversations you wanna try e.g.
console.error('Couldnt JSON parse', e);
if(toParse.split(',').length > 0) return toParse.split(',');
}
}
render(){
if(!this.cards) this.cards = this.getDataFromProperty(this.cards);
return (
{this.cards.map(card) => {
return (
<div>
<h1>{card.cardTitle}</h1>
<p>{card.copy}</p>
</div>
);
})}
)
}
<stencil-component
cards = '[{"cardTitle": "placeholder", "copy": "copy1"},{"cardTitle": "placeholder2", "copy": "copy3"}]'>
</stencil-component>
Try and Catch will prevent some hard errors and give you informations what happened if it couldn't be parsed. Maybe you have to tweak it a bit for your needs but the concept works. In the catch
condition you can try some other techniques for data conversation.
Secondly i wanna share a complete different approach that depends on the environment you are using but you can use a public method. Than you can share data to the web component directly:
@Prop() cards: Array<object> = [];
@Method() setData(data){
this.cards = data;
}
render(){
//your render function as it was
}
Inside your HTML
<stencil-component id="web-component"></stencil-component>
<script>
let data = '[{"cardTitle": "placeholder", "copy": "copy1"},{"cardTitle": "placeholder2", "copy": "copy3"}]';
document.getElementById("web-component").setData(data);
//just call the setData function from outside works with jquery too
</script>
But there is one little thing you have to notice in that approach. Maybe your render function won't be called than you can do it manually in that function by just using this.render();
or you can use the @State
decorator in front of your variable.