Passing a PHP variable to JavaScript in a Blade template
JavascriptLaravelLaravel BladeJavascript Problem Overview
is there any ways that JavaScript can get the variable from the controller in a Laravel Blade template?
Example: I have the code below:
$langs = Language::all();
return View::make('NAATIMockTest.Admin.Language.index',compact('langs'));
Can I get $langs
and pass it to JavaScript? I already used PHP-Vars-To-Js-Transformer. But when I use JavaScript::put()
for two functions in the controller. It didn't work. Any help?
This is my create function in the controller:
public function create()
{
$names = $this->initLang();
Javascript::put([
'langs' => $names
]);
return View::make('NAATIMockTest.Admin.Language.create',compact('names'));
}
this is my view:
@extends('AdLayout')
@section('content')
<script type="text/javascript">
var app = angular.module('myApp', []);
app.controller('langCtrl', function($scope) {
$scope.languages = langs;
});
</script>
<div class="container-fluid" ng-app="myApp" ng-controller="langCtrl">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">
<h2>Create language</h2>
</div>
<div class="panel-body">
{!! Form::open() !!}
<p class="text-center">
{!! Form::label('Name','Language: ') !!}
<input type="text" name="searchLanguage" ng-model="searchLanguage">
</p>
<select name="Name[]" multiple size="10" ng-model="lang" ng-click="show()">
<option value="@{{v}}" ng-repeat="(k,v) in languages | filter:searchLanguage">
@{{v}}
</option>
</select><br>
<div class="text-center">
{!! Form::submit('Create',['class'=>'btn btn-primary']) !!}
{!! Html::linkAction('NAATIMockTest\LanguageController@index', 'Back', null, array('class' => 'btn btn-primary')) !!}
</div>
{!! Form::close() !!}
</div>
</div>
</div>
</div>
</div>
@endsection
my javascript.php in config folder:
<?php
return [
'bind_js_vars_to_this_view' => 'footer',
'bind_js_vars_to_this_view' => 'NAATIMockTest.Admin.Language.create',
'bind_js_vars_to_this_view' => 'NAATIMockTest.Admin.Language.edit',
'js_namespace' => 'window',
];
The idea is: I have a table language in MySQL. I want to show the dropdown list with multiple attributes to choose, and I also want to search with angularjs as well. That's why I want to pass the variable from the controller to JavaScript. Additionally, I have the function inside LanguageController called initLang to check if any language is exist inside the database, it isn't displayed inside the dropdown list in create the view.
Javascript Solutions
Solution 1 - Javascript
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>
Solution 2 - Javascript
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>
Solution 3 - Javascript
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.
Solution 4 - Javascript
$langs = Language::all()->toArray();
return View::make('NAATIMockTest.Admin.Language.index', [
'langs' => $langs
]);
then in view
<script type="text/javascript">
var langs = {{json_encode($langs)}};
console.log(langs);
</script>
Its not pretty tho
Solution 5 - Javascript
Is very easy, I use this code:
Controller:
$langs = Language::all()->toArray();
return view('NAATIMockTest.Admin.Language.index', compact('langs'));
View:
<script type="text/javascript">
var langs = <?php echo json_decode($langs); ?>;
console.log(langs);
</script>
hope it has been helpful, regards!
Solution 6 - Javascript
The best way is to put it in a hidden div in php blade
<div hidden id="token">{{$token}}</div>
then call it in javascript as a constant to avoid undefined var errors
const token = document.querySelector('div[id=token]').textContent
// console.log(token)
// eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiI5MjNlOTcyMi02N2NmLTQ4M2UtYTk4Mi01YmE5YTI0Y2M2MzMiLCJqdGkiOiI2Y2I1ZGRhNzRhZjNhYTkwNzA3ZjMzMDFiYjBiZDUzNTZjNjYxMGUyZWJlNmYzOTI5NzBmMjNjNDdiNjhjY2FiYjI0ZWVmMzYwZmNiZDBmNyIsImlhdCI6IjE2MDgwODMyNTYuNTE2NjE4IiwibmJmIjoiMTYwODA4MzI1Ni41MTY2MjUiLCJleHAiOiIxNjIzODA4MDU2LjMxMTg5NSIsInN1YiI6IjUiLCJzY29wZXMiOlsiYWRtaW4iXX0.GbKZ8CIjt3otzFyE5aZEkNBCtn75ApIfS6QbnD6z0nxDjycknQaQYz2EGems9Z3Qjabe5PA9zL1mVnycCieeQfpLvWL9xDu9hKkIMs006Sznrp8gWy6JK8qX4Xx3GkzWEx8Z7ZZmhsKUgEyRkqnKJ-1BqC2tTiTBqBAO6pK_Pz7H74gV95dsMiys9afPKP5ztW93kwaC-pj4h-vv-GftXXc6XDnUhTppT4qxn1r2Hf7k-NXE_IHq4ZPb20LRXboH0RnbJgq2JA1E3WFX5_a6FeWJvLlLnGGNOT0ocdNZq7nTGWwfocHlv6pH0NFaKa3hLoRh79d5KO_nysPVCDt7jYOMnpiq8ybIbe3oYjlWyk_rdQ9067bnsfxyexQwLC3IJpAH27Az8FQuOQMZg2HJhK8WtWUph5bsYUU0O2uPG8HY9922yTGYwzeMEdAqBss85jdpMNuECtlIFM1Pc4S-0nrCtBE_tNXn8ATDrm6FecdSK8KnnrCOSsZhR04MvTyznqCMAnKtN_vMDpmIAmPd181UanjO_kxR7QIlsEmT_UhM1MBmyfdIEvHkgLgUdUouonjQNvOKwCrrgDkP0hkZQff-iuHPwpL-CUjw7GPa70lp-TIDhfei8T90RkAXte1XKv7ku3sgENHTwPrL9QSrNtdc5MfB9AbUV-tFMJn9T7k
Solution 7 - Javascript
2022
Laravel has been updated so this can now be simplified to:
<script>const langs = {{ Js::from(Language::all()) }};</script>
Or, for any PHP object:
<script>const jsObject = {{ Js::from($phpObject) }};</script>
This also adds the JSON_HEX_TAG
s mentioned in Ken's answer.
Solution 8 - Javascript
View
<script>
var langs = JSON.parse({!! json_encode($langs) !!});
</script>
Solution 9 - Javascript
It's Simple and It worked for me...
Just pass the PHP variable into single quotes...
<script>
var collection = '{{ $collection }}';
</script>