I can't set Session Items in laravel inertia - laravel

I am using Laravel with inertia, but I am not able to set session items in laravel.
here is my laravel code:
use Illuminate\Support\Facades\Session;
public function index()
{
Session::put('message', 'showCatergories');
$categories = Category::all();
return Inertia::render('Admin/Categories', ['categories' => $categories]);
}
nothing appears in application -> storage-> sessoin storage
my route:
Route::middleware(['auth', 'web'])->group(function () {
Route::resource('/categories', CategoriesController::class);
});
How to tackle this issue?

Working with session items and flash messages in Inertia.js is done by appending it to the shared method in the HandleInertiaRequests middleware.
class HandleInertiaRequests extends Middleware
{
public function share(Request $request)
{
return array_merge(parent::share($request), [
'flash' => [
'message' => fn () => $request->session()->get('message')
],
]);
}
}
Here we get the message item on the session and append it as a flash prop on the request.
Then we can use it in our frontend of choice. Here is a React.js example:
import { usePage } from '#inertiajs/inertia-react'
export default function Layout({ children }) {
const { flash } = usePage().props
return (
<main>
<header></header>
<content>
{flash.message && (
<div class="alert">{flash.message}</div>
)}
{children}
</content>
<footer></footer>
</main>
)
}
You can read more about flash messages in the documentation.

Related

How can I make to redirect from axios code wwhen invalid access?

With Laravel 9/Inertiajs 3 I have page under adminarea with checking that user is logged as admin:
My vuejs page is container vue file and I read data using axios(that gives me possibility to run filter without all page reloading) :
axios.post(route('admin.currencies.filter'), filters)
.then(({data}) => {
currencyRows.value = data.data
})
.catch(e => {
showRTE(e) // custom error
console.error(e)
})
and :
<?php
class CurrencyController extends Controller
{
public function index()
{
if ( ! auth()->user()->can(ACCESS_APP_ADMIN_LABEL)) {
return redirect(route('admin.dashboard.index'))
->with( 'flash', 'You have no access to currencies listing page')
->with('flash_type', 'error');
}
return Inertia::render('Admins/Currencies/Index', []);
}
public function filter()
{
\Log::info( varDump(-9, ' -9 filter::') );
if ( ! auth()->user()->can(ACCESS_APP_ADMIN_LABEL)) {
\Log::info( varDump(-98, ' -98 INSIDE filter::') );
return redirect(route('admin.dashboard.index'))
->with( 'flash', 'You have no access to currencies filter method')
->with('flash_type', 'error');
}
...
$currencies = Currency
::getByName($filter_name)
->orderBy($order_by, $order_direction)
->paginate($backend_items_per_page, array('*'), 'page', $page);
return (CurrencyResource::collection($currencies)); // collection of resources
} // public function filter()
...
php>
The problem is that when in filter method invalid access code is run(I check it in file) app is not redirecred to dasboard page, but is run next
and I got javascript error as filter method did not return valid data which are expected on client...
Looks like redirect can not be run from axios code... How that can be done?
Thanks!
You may change axios to this.$inertia : [https://inertiajs.com/manual-visits]
this.$inertia.post(this.route('...'),{},{
only:['...']
});

.isDirty is true after submitting and reloading InertiaJS page

I have a simple form with a "Save" button that shows up if the user has updated any of the checkboxes.
The form sends a POST request to a store route in a controller that creates new records in the databases and redirects them to the index route.
When the page reloads, it doesn't seem to reset the Inertia form isDirty state from true to false even when I manually refresh the page.
public function index(Request $request)
{
$restaurantCategories = auth()->user()
->currentTeam->categories()
->with('category')->get();
$allCategories = Category::all();
$filters = $request->only('search');
return Inertia::render('Restaurant/Categories/Index',
[
'restaurantCategories' => $restaurantCategories,
'allCategories' => $allCategories, 'filters' => $filters
]);
}
public function store(Request $request)
{
foreach (auth()->user()->currentTeam->categories as $category) {
$category->delete();
}
foreach ($request->checkedCategories as $category) {
auth()->user()->currentTeam->categories()
->create(['category_id' => $category['id']]);
}
return redirect()->route('restaurant.categories.index');
}
Vue
export default{
props: {
filters: Object,
restaurantCategories: Object,
allCategories: Object,
},
data: {
updateForm: this.$inertia.form({
checkedCategories: this.restaurantCategories.map(
(resCat) => resCat.category
),
}),
}
}
methods:{
//THIS METHOD IS CALLED WHEN THE SAVE BUTTON IS CLICKED
sendUpdate() {
this.$inertia.post(
this.route("restaurant.categories.store"),
this.updateForm
);
},
},
}
I've tried setting a key to the save button and updating the key on sendUpdate method, and calling Inertia.reload()

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()
]);
}

How to Add Roles and Permission to Laravel Fortify + Inertia + vue?

my project use laravel fortify, inertia with vue. i have to add role based permissions (just like spatie permissions package). i'm still a beginner to fortify and inertia. but i have experience in spatie package. i'm stuck with how add roles and permission to fortify. currently i'm planning to create table structure like spatie package have(roles, permssions, roles_has_permissions ,etc). is there per-build package or better way to implement roles and permissions ? and use '#can' in vue files? thank you.
edit
hello guys,this is i'm currently did(im using this now ). it is working but still need some improvements, (any better solution i really appreciate it)
1)installed and configured as usual spatie/laravel-permission
2)added predefined permissions and roles to tables using seeder
created function in user model to get permission array list
// user model function
public function getPermissionArray()
{
return $this->getAllPermissions()->mapWithKeys(function($pr){
return [$pr['name'] => true];
});
}
and added that function to inertia middleware
//App\Http\Middleware\HandleInertiaRequests
public function share(Request $request)
{
return array_merge(parent::share($request), [
'auth'=>['user' => $request->user() ? $request->user()->only('id', 'name', 'email') : null,
'can' =>$request->user() ? $request->user()->getPermissionArray() : []
],
]);
}
now $page.props.auth.can can access globally
added permission check in vue file
<div class="row">
<div class="col-sm-12 col-md-6" v-if="$page.props.auth.can['user_create']">
<inertia-link
class="btn btn-primary"
:href="$route('admin.user.create')"
>Create New
</inertia-link>
</div>
</div>
I resolved issue like below,
first I'm sending permission array to UI.
in user model
<?php
// user model function
public function getPermissionArray()
{
return $this->getAllPermissions()->mapWithKeys(function($pr){
return [$pr['name'] => true];
});
}
in inertia share middleware
<?php
//App\Http\Middleware\HandleInertiaRequests
public function share(Request $request)
{
return array_merge(parent::share($request), [
'auth'=>['user' => $request->user() ? $request->user()->only('id', 'name', 'email') : null,
'can' =>$request->user() ? $request->user()->getPermissionArray() : []
],
]);
}
in app js file, I have added global function to check one or many permssion have user
import Vue from 'vue'
Vue.mixin({
methods: {
hasAnyPermission: function (permissions) {
var allPermissions = this.$page.props.auth.can;
var hasPermission = false;
permissions.forEach(function(item){
if(allPermissions[item]) hasPermission = true;
});
return hasPermission;
},
},
})
in vue components :
<script>
export default {
data() {
return {};
},
mounted: function () {},
methods: {},
};
</script>
<template>
<div>
<li v-if="hasAnyPermission(['testiml_view', 'testiml_edit', 'testiml_create'])">
<inertia-link
:href="$route('admin.testimonial.index')"
class="side-nav-link-a-ref"
>
<i class="fas fa-feather"></i>
<span>Testimonial</span>
</inertia-link>
</li>
</div>
</template>
in the share method on the Inertia Middleware: HandleInertiaRequest.php, I passed the permissions and the roles array to Vue using:
$permissions = $user->getAllPermissions()->pluck('name');
$roles = $user->roles()->pluck('name');
return array_merge(parent::share($request), [
'auth.user' => fn() => $request->user() ?
$request->user()->only('id', 'name', 'email', 'roles')
: null,
'auth.user.permissions' => $permissions,
'auth.user.roles' => $roles
]);

PUT errors in Vue

I'm trying to update data using laravel. I'm not sure why I can't access the PUT api. I tied so switch the api to store the data vs update and that works. I can't see anything wrong with the code.
Here is the api router
Route::put('product', 'ProductController#update');
here is the controller
public function update(Request $request, $id)
{
$product= Product::findOrFail($id);
$product->update($request->all());
return ['message' => "Success"];
}
Here is the vue.js
methods: {
updateProduct(id){
this.$Progress.start();
this.form.put('api/product/'+this.form.id)
.then(() => {
// success
$('#addNew').modal('hide');
Swal.fire(
'Updated!',
'Information has been updated.',
'success'
)
this.$Progress.finish();
Fire.$emit('AfterCreated');
})
.catch(() => {
this.$Progress.fail();
});
},
In the Vue component I have a modal with a form
<form #submit.prevent ="editmode ? updateProduct() : createProduct()">
The error I'm getting is
405 (Method Not Allowed)
The error I was getting was in the api router.
Route::put('product/{id}', 'ProductController#update');

Resources