check if data passed from laravel to vue exists - laravel

Sometimes I need to pass data from my controller to the view and sometimes I dont!
But when theres no data passed I get this error:
Undefined variable: tutorial (View:
/var/www/html/resources/views/home.blade.php)
No data example:
public function index()
{
return view('home');
}
Containg data example
public function tutorial()
{
return view('home', ['tutorial' => 'Welcome to myproject, lets get started!!!']);
}
Blade:
beforeMount()
{
let tutorial = {{ var_export($tutorial) }} // ERROR!!
if (tutorial) {
return
}
this.reloadData()
}
I think I can do this way in my index function:
public function index()
{
return view('home', ['tutorial' => []);
}
But its just gross!! Theres anyway to check if data passed from laravel exists in my vue??

Because you cannot just put the Laravel variable in js.
Options to solving the problem included:
Performing an api request for the data using the application
component once it had been mounted.
Attaching the data into the
Javascript context using the blade template.
You can do some thing like this:
<Home tutorial="{{ $tutorial }}"> <!-- make tutorial become to props -->
</Home>
And in your view component:
Vue.component('Home', {
props: [
{
name: 'tutorial', // add this props
default: '',
}
],
beforeMount()
{
if (this.tutorial) { // use like this.tutorial
return
}
this.reloadData()
}
});

Related

Axios gives undefined while accessing data at Vue's componenet in Laravel

I'm using Laravel and Vue's component, and when i try to access the banners property from response returned by axios in vue component it gives me undefined.
I am accessing the perperty like response.data.banners
I'm returning data from controller in following way:
public function getBanners(Request $request){
return response()->json(['
banners'=> BannerImage::active()->get()
]);
}
Here is how i am accessing axios response
<script>
export default {
data: function() {
return {
banners: []
}
},
mounted() {
axios.get("getBanners").then((res)=> {
console.log(res);
console.log(res.data);
console.log(res.data.banners);
this.banners = res.data.banners;
});
console.log('Component mounted.')
}
}
</script>
Response by axios
All is working before accessing the banners property. Is there anything i am not doing correct ?
You have an linebreak ↩ between ' and banners, which is shown in the console line 2 "↩ banners":
Problem
public function getBanners(Request $request){
return response()->json([' // <-- ↩ line break
banners'=> BannerImage::active()->get()
]);
}
Correct
public function getBanners(Request $request) {
return response()->json([
'banners' => BannerImage::active()->get()
]);
}

Laravel - how to add variable type to parameter of controller method

I have a controller method that has a parameter. I need to add a type to it:
public function deleteIndex(int $user_id)
{
return DB::try(function () use ($user_id) {
if (empty($user_id)) {
return error(trans('user.invalid_data_recheck'));
}
$user = User::find($user_id);
if (empty($user)) {
return error(trans('user.invalid_user'));
}
if (!$user->delete()) {
return error(trans('user.could_not_delete_user'));
}
return success();
});
}
The route looks like this:
AdvancedRoute::controllers([
'users' => 'API\UserAPIController'
]);
From the JS the parameter is being sent like this: '/users/{user_id}'
The issue I have is, when I add the parameter type: "int" in the controller method, the endpoint is no longer reached, if I remove "int" everything works fine. But I need that for an openapi library that I use. Any help is appreciated!

Vue.js with Laravel Permission

I am in the process of integrating Laravel Permission API with Vue.JS frontend. I am using https://github.com/spatie/laravel-permission library for Laravel Permission. I am not understanding how can I check permission in the Vue JS front End (In Laravel blade I am using #Can to check the permission).
I will do a ajax call to check for permissions instead , something like this, but of cours eyou need to modify it to cater your needs.
Routes:
Route::get('/permission/{permissionName}', 'PermissionController#check');
Controller:
function check($permissionName) {
if (! Auth::user()->hasPermissionTo($permissionName)) {
abort(403);
}
return response('', 204);
}
Vue: (if you wanna do this synchronously), this is a simple example (Vue global mixin), you can turn this into Vue directive or component.
Vue.mixin("can", (permissionName) => {
let hasAccess;
axios.get(`/permission/${permissionName}`)
.then(()=> {
hasAccess = true;
}
.catch(()=> {
hasAccess = false;
};
return hasAccess;
});
And then everytime you wanna check permission, you can just do
<el-input v-if="can('write-stuff')"> </el-input>
I'm literally working on this exact same thing. I'm thinking of adding a custom Vue directive that would check against the Laravel.permissions array.
It might even be as simple as
Vue.directive('can', function (el, binding) {
return Laravel.permissions.indexOf(binding) !== -1;
})
I haven't tested this code. Just brainstorming here.
<button v-can="editStuff">You can edit this thing</button>
I can hold permissions this way:
window.Laravel = <?php echo json_encode([
'csrfToken' => csrf_token(),
'userId' => Auth::user()->id,
'permissions' => Auth::user()->permissions()->pluck('name')->toArray()
]); ?>
Just stumbled upon this problem and I would like to share what I found and implemented.
Add an accessor on the User model the spatie/laravel-permission is using
public function getAllPermissionsAttribute() {
$permissions = [];
foreach (Permission::all() as $permission) {
if (Auth::user()->can($permission->name)) {
$permissions[] = $permission->name;
}
}
return $permissions;
}
On your global page or layout page pass the permission from the accessor to the javascript.
<script type="text/javascript">
#auth
window.Permissions = {!! json_encode(Auth::user()->allPermissions, true) !!};
#else
window.Permissions = [];
#endauth
</script>
Create a global directive on resources/js/app.js
Vue.directive('can', function (el, binding, vnode) {
if(Permissions.indexOf(binding.value) !== -1){
return vnode.elm.hidden = false;
}else{
return vnode.elm.hidden = true;
}
})
Here you are checking if the permission you supplied on the directive is on the permission array from laravel.
If found then it will hide the element else show, this function is like a v-if.
Use it like this on your component - "add_items" is your permission
<button type="button" v-can="'add_items'"></button>
This solution is from this but instead of a mixin, I use a directive.
Got the idea of directive from #Ismoil Shifoev comment above.
You can use this format in Vuejs for Laravel Permission:
<div v-if="can('edit post')">
<!-- Edit post form -->
</div>
<div v-if="is('super-admin')">
<!-- Show admin tools -->
</div>
add function to User Model to get all user permissions&roles like this:
class User extends Authenticatable
{
// ...
public function jsPermissions()
{
return json_encode([
'roles' => $this->getRoleNames(),
'permissions' => $this->getAllPermissions()->pluck('name'),
]);
}
}
pass this data to JavaScript in HTML header:
<script type="text/javascript">
window.Laravel = {
csrfToken: "{{ csrf_token() }}",
jsPermissions: {!! auth()->check()?auth()->user()->jsPermissions():null !!}
}
</script>
in app.js file add global Vuejs can function to check user permissions and is function to check user roles:
Vue.prototype.can = function(value){
return window.Laravel.jsPermissions.permissions.includes(value);
}
Vue.prototype.is = function(value){
return window.Laravel.jsPermissions.roles.includes(value);
}
https://github.com/ahmedsaoud31/laravel-permission-to-vuejs
I would go with Ralph solution. But I find myself better using. This function to fetch the Permissions.
public function getAllPermissionsAttribute() {
return Auth::user()->getAllPermissions()->pluck('name');
}
Just a bit cleaner, and since I tend to use Roles instead of particular permissions for each User, this solution should work as well.

How to retrieve User name in Vue component with Laravel

I have a vue component that will send a message and I want to send the logged in user name. I'm using laravel 5.5
methods:{
sendMessage(){
this.$emit('messagesent', {
message:this.messageText,
user: {
name : {{Auth()::user()->name}} //Here is where it should be
}
});
this.messageText = '';
}
}
I already tried using
{{Auth()::user()->name}}
Auth()::user()->name
Both give errors. How can I retrieve the name?
Depend on your approach, this can be achieve in different ways
1. Pass in the username from the view
<send-message user={{ $user->username }} ></send-message>
then inside your vuejs component
export default {
props: ['user'],
data(){
return {
user: ''
}
},
methods: {
sendMessage(){
var user = JSON.parse(this.user)
//do you thing here
}
},
}
2. Bind the user information to window object on your page header
<script>
window.user = {!! json_encode([
'user' => $user->username,
]) !!};
</script>

Laravel.54 pass data to action controller

I need to get 'mp3' value in controller !
( to check posts from mp3s type )
my post types :
video, album , mp3
(web.php)
Route::group(array('prefix' => 'mp3s'), function($pt) {
Route::get("/", "PostController#archivePosts");
Route::get("mp3/{slug}", "PostController#singlePost");
});
Route::group(array('prefix' => 'albums'), function($pt) {
Route::get("/", "PostController#archivePosts");
Route::get("album/{slug}", "PostController#singlePost");
});
Route::group(array('prefix' => 'videos'), function($pt) {
Route::get("/", "PostController#archivePosts");
Route::get("video/{slug}", "PostController#singlePost");
});
#danial dezfooli
To Get Prefix value you can inject Request Dependency inside controller's method as below.
public function index(\Illuminate\Http\Request $request){
dd($request->route()->getPrefix());
}
or you can do in another way also
public function index(){
dd($this->getRouter()->getCurrentRoute()->getPrefix());
}
For more reference you can refer : Laravel 5 get route prefix in controller method
Route::get("mp3/{slug}", "PostController#singlePost");
In PostController, you can get it like
public function singlePost($slug) {
dd($slug)// to check slug value
}

Resources