DEV Community

Cover image for Sharing data from Laravel components to Alpine
Félix Dorn
Félix Dorn

Posted on • Updated on

Sharing data from Laravel components to Alpine

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

Which would output (given that $open is true):

<div> x-data="{ open: true }">

</div>
Enter fullscreen mode Exit fullscreen mode

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;
});
Enter fullscreen mode Exit fullscreen mode

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));
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
kondratovbr profile image
Bogdan Kondratov • Edited

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 ifs with some substr 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.

Collapse
 
felixdorn profile image
Félix Dorn

I've actually caught this bug a week ago and forgot to update the snippet! Good catch!

Collapse
 
w3bdesign profile image
w3bdesign

Your link is broken, it should link to github.com/ImLiam/laravel-blade-he...

Collapse
 
felixdorn profile image
Félix Dorn

Fixed!

Collapse
 
zubairmohsin33 profile image
Zubair Mohsin

That's a good tip right there. Thanks for sharing this.

Collapse
 
felixdorn profile image
Félix Dorn

Thanks!