jjudge's avatar
Level 9

Is Js::from() the right way to insert JSON into a template?

I'm inserting JSON into a livewire button component, and trying to find the best way (most robust and safest).

When passing JSON into a standard HTML element, @json can be used:

<button wire:click="$emit('openModal', 'my-modal','@json($data)')>...

That is parsed by blade and converts $data to JSON.

When using a blade component, say x-button this may not work. I'm finding the @json() is going into the final HTML element verbatim, so is not getting expanded. Instead I need to do this:

<x-button wire:click="$emit('openModal', 'my-modal','{!! json_encode($data) !!}')>...

I think that gets parsed by blade before the component runs, so it works like @json().

What I have used in place of json_encode() is Js::from().... This also works, similar to json_encode() but provides a few additional useful options.

Now the question: Js::from() feels neater, closer to the way blade should work. However, it's not documented anywhere, is not used in any SO answers or blade tutorials I can find, it's not even a Facade, though blade seems to have access to it globally as though it were. It's like it does not exist, but I've used it on and off for years.

So, should I use {!! Js::from() !!} or {!! json_encode() !!} in my blade views, where @json() does not work?

0 likes
1 reply
LaryAI's avatar
Level 58

In Blade templates, when you need to insert JSON data into your HTML, you have a few options. The @json directive is a common and convenient way to handle this, but as you've noticed, it doesn't always work in every context, such as within Blade components.

Using json_encode()

The json_encode() function is a reliable way to convert PHP arrays or objects into JSON strings. When you use it within Blade templates, you often need to use the {!! !!} syntax to avoid escaping the JSON string.

Example:

<x-button wire:click="$emit('openModal', 'my-modal', '{!! json_encode($data) !!}')">...

Using Js::from()

The Js::from() method is part of the Laravel JavaScript package, which provides a more expressive way to handle JavaScript variables in Blade templates. It can be particularly useful for more complex data structures or when you need additional options.

Example:

<x-button wire:click="$emit('openModal', 'my-modal', '{!! Js::from($data) !!}')">...

Which One to Use?

Both json_encode() and Js::from() are valid options, but Js::from() offers a few advantages:

  1. Expressiveness: Js::from() is more expressive and can handle more complex data structures.
  2. Consistency: It aligns better with the way Blade templates are designed to work, making your code more readable and maintainable.

However, Js::from() is not as widely documented or known, which might be a concern for some developers. If you are working in a team or on a project where maintainability and readability by others are important, you might want to stick with json_encode().

Conclusion

Both methods are valid, but if you prefer a more expressive and potentially more powerful solution, you can use Js::from(). Just be aware that it might not be as familiar to other developers.

Here is a final example using both methods for clarity:

Using json_encode()

<x-button wire:click="$emit('openModal', 'my-modal', '{!! json_encode($data) !!}')">...

Using Js::from()

<x-button wire:click="$emit('openModal', 'my-modal', '{!! Js::from($data) !!}')">...

Choose the one that best fits your needs and the context of your project.

Please or to participate in this conversation.