This article is old. There is a new, better method to do this directly in Laravel.
You can use @json($data)
or @js($data)
now. This article is a relic of the past.
If you ever tried to pass data from blade to alpine, you probably had to json_encode
arrays or convert booleans to strings.
<div x-data="{ open: {{ $open ? 'true' : 'false' }">
{{-- Simplicity is the ultimate sophistication. - Leonardo da Vinci --}}
</div>
It's even worse with arrays because you also have to convert double quotes to single quotes to avoid conflicts with the x-data
's quotes
I've made a little helper to ease this process it looks like this:
<div x-data="{ @alpine($open) }">
</div>
Which would output (given that $open is true):
<div> x-data="{ open: true }">
</div>
Let's dive in quickly to the directive that makes this works.
Blade::directive('alpine', function (string $variables) {
return <<<DIRECTIVE
<?php
\$data = array_combine(
array_map(
fn (\$variable) => str_replace('$', '', \$variable),
explode(',', '$variables')
),
[$variables]
);
\$replaced = str_replace(["'", '"'], ["\'", "'"], json_encode(\$data));
if (str_starts_with(\$replaced, '{')) {
\$replaced = substr(\$replaced, 1);
}
if (str_ends_with(\$replaced, '}')) {
\$replaced = substr(\$replaced, 0, -1);
}
echo \$replaced;
?>
DIRECTIVE;
});
This bit of code might seem complicated at first but it's mostly because of the limitations of custom Blade directives.
I highly recommend checking out https://github.com/ImLiam/laravel-blade-helper for an easier time with Blade directives.
Anyway, I'll just explain the important part:
str_replace(["'", '"'], ["\'", "'"], json_encode(\$data));
After converting the data to JSON, we escape single quotes and then convert double quotes to single quotes, which means that even if you're data contains single quotes, it'll work seamlessly.
I'd love some feedback as this is my first article ever (!)
Top comments (6)
Doesn't exactly work if your data ends with an array or an object - it trims ALL curly brackets from the end but it should only remove the last one. So, some
if
s with somesubstr
would actually be better.But nice snippet nevertheless.
Upd.: It also need to trim spaces from extracted variable names. Like this for example:
fn (\$variable) => str_replace('$', '', trim(\$variable, ' '))
Otherwise the spaces are kept as part of the keys breaking everything.
I've actually caught this bug a week ago and forgot to update the snippet! Good catch!
Your link is broken, it should link to github.com/ImLiam/laravel-blade-he...
Fixed!
That's a good tip right there. Thanks for sharing this.
Thanks!