Passing a PHP variable to JavaScript in a Blade template
One working example for me.
Controller:
public function tableView(){ $sites = Site::all(); return view('main.table', compact('sites'));}
View:
<script> var sites = {!! json_encode($sites->toArray()) !!};</script>
To prevent malicious / unintended behaviour, you can use JSON_HEX_TAG
as suggested by Jon in the comment that links to this SO answer
<script> var sites = {!! json_encode($sites->toArray(), JSON_HEX_TAG) !!};</script>
Standard PHP objects
The best way to provide PHP variables to JavaScript is json_encode
. When using Blade you can do it like following:
<script> var bool = {!! json_encode($bool) !!}; var int = {!! json_encode($int) !!}; /* ... */ var array = {!! json_encode($array_without_keys) !!}; var object = {!! json_encode($array_with_keys) !!}; var object = {!! json_encode($stdClass) !!};</script>
There is also a Blade directive for decoding to JSON
. I'm not sure since which version of Laravel but in 5.5 it is available. Use it like following:
<script> var array = @json($array);</script>
Jsonable's
When using Laravel objects e.g. Collection
or Model
you should use the ->toJson()
method. All those classes that implements the \Illuminate\Contracts\Support\Jsonable
interface supports this method call. The call returns automatically JSON
.
<script> var collection = {!! $collection->toJson() !!}; var model = {!! $model->toJson() !!};</script>
When using Model
class you can define the $hidden
property inside the class
and those will be filtered in JSON
. The $hidden
property, as its name describs, hides sensitive content. So this mechanism is the best for me. Do it like following:
class User extends Model{ /* ... */ protected $hidden = [ 'password', 'ip_address' /* , ... */ ]; /* ... */}
And somewhere in your view
<script> var user = {!! $user->toJson() !!};</script>
Let's say you have a collection named $services
that you are passing to the view.
If you need a JS array with the names, you can iterate over this as follows:
<script> const myServices = []; @foreach ($services as $service) myServices.push('{{ $service->name }}'); @endforeach</script>
Note: If the string has special characters (like รณ
or HTML code), you can use {!! $service->name !!}
.
If you need an array of objects (with all of the attributes), you can use:
<script> const myServices = @json($services); // ...</script>
Note: This blade directive @json
is not available for old Laravel versions. You can achieve the same result using json_encode
as described in other answers.
Sometimes you don't need to pass a complete collection to the view, and just an array with 1 attribute. If that's your case, you better use $services = Service::pluck('name');
in your Controller.