I am converting certain php data to json for use in my front end javascript.
I have an array of product variants, an array of images from a media field that is defined on my variants, and an array of the url attributes of that asset field. All this on the twig side works as expected.
However, when I log the js objects post-conversion, they seem to be missing some attributes. Notably, the variant objects in js don't have the variantMedia attribute, and the image objects don't have the url attribute, even though on the twig side the map filter is able to access those attributes just fine.
Why is this? Are some element properties "dynamic" in the sense that craft generates them on the fly? Is there a way to make these element fields resolve to properties on the source php array such that json_encode will capture them?
Minimal working example of code:
{% do craft.app.elements.eagerLoadElements(
className(product),
[product],
[['variants.variantMedia']]
) %}
{% set variants = product.variants %}
{% set variantMedia = product.variants|map(variant => variant.variantMedia[0] ?? null)|filter(media => media is not null) %}
{% set variantMediaURL = variantMedia|map(media => media.url ?? null)|filter(media => media is not null) %}
<script>
var variants = {{ to_json(variants) }}
console.log(variants.map(v => v.variantMedia))
var media = {{ to_json(variantMediae) }}
console.log(media)
console.log(media.map(m => m.url))
var url = {{ to_json(variantMediaeURL) }}
console.log(url)
</script>
to_json
is just a twig macro for converting php arrays to json as defined here
{% macro to_json(php_array) %}
{{ php_array|json_encode|replace("'", "'")|raw }}
{% endmacro %}
Console logs, where attributes are missing:
// console.log(variants.map(v => v.variantMedia)) - list is empty when generated through js map function
[null, null]
// console.log(media) - list is non-empty when generated through twig map
[
{
"id": 51,
... // attributes trimmed
"newFolderId": null,
"tempFilePath": null,
"avoidFilenameConflicts": false,
"suggestedFilename": null,
"conflictingFilename": null,
"deletedWithVolume": false,
"keepFileOnDelete": false
}
]
// console.log(media.map(m => m.url)) - list is empty when generated through js map function
[null]
// console.log(url) - list is non-empty when generated through twig map
["https://mystore.com/uploads/images/test-image.jpeg"]