ToxifiedM

Member Since 7 Months Ago

Experience Points
3,470
Total
Experience

1,530 experience to go until the next level!

In case you were wondering, you earn Laracasts experience when you:

  • Complete a lesson — 100pts
  • Create a forum thread — 50pts
  • Reply to a thread — 10pts
  • Leave a reply that is liked — 50pts
  • Receive a "Best Reply" award — 500pts
Lessons Completed
7
Lessons
Completed
Best Reply Awards
0
Best Reply
Awards
  • start your engines Created with Sketch.

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • first-thousand Created with Sketch.

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • 1-year Created with Sketch.

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • 2-years Created with Sketch.

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • 3-years Created with Sketch.

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • 4-years Created with Sketch.

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • 5-years Created with Sketch.

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • school-in-session Created with Sketch.

    School In Session

    Earned when at least one Laracasts series has been fully completed.

  • welcome-newcomer Created with Sketch.

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • full-time-student Created with Sketch.

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • pay-it-forward Created with Sketch.

    Pay It Forward

    Earned once you receive your first "Best Reply" award on the Laracasts forum.

  • subscriber Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • evangelist Created with Sketch.

    Laracasts Evangelist

    Earned if you share a link to Laracasts on social media. Please email [email protected] with your username and post URL to be awarded this badge.

  • chatty-cathy Created with Sketch.

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • lara-veteran Created with Sketch.

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • 10k-strong Created with Sketch.

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • lara-master Created with Sketch.

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • laracasts-tutor Created with Sketch.

    Laracasts Tutor

    Earned once your "Best Reply" award count is 100 or more.

  • laracasts-sensei Created with Sketch.

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • top-50 Created with Sketch.

    Top 50

    Earned once your experience points ranks in the top 50 of all Laracasts users.

  • Community Pillar

    Earned once your experience points ranks in the top 10 of all Laracasts users.

Level 1
3,470 XP
Apr
22
3 weeks ago
Activity icon

Awarded Best Reply on How Can I Use Handler _.throttle Function Within Watch Function In Vue 3 Composition API?

Here is the solution to the above. Incase any one needs it in the future.

watch(filters,
    _.throttle(() => {
        let query = _.pickBy(filters);
        let queryRoute = route('users.index', Object.keys(query).length ? query : {
            remember: 'forget'
        });
        Inertia.get(queryRoute, {}, {
            only: ['usersData'],
            preserveState: true,
            preserveScroll: true
        });
    }, 200), {
        deep: true
    }
);
Activity icon

Replied to How Can I Use Handler _.throttle Function Within Watch Function In Vue 3 Composition API?

Here is the solution to the above. Incase any one needs it in the future.

watch(filters,
    _.throttle(() => {
        let query = _.pickBy(filters);
        let queryRoute = route('users.index', Object.keys(query).length ? query : {
            remember: 'forget'
        });
        Inertia.get(queryRoute, {}, {
            only: ['usersData'],
            preserveState: true,
            preserveScroll: true
        });
    }, 200), {
        deep: true
    }
);
Activity icon

Started a new Conversation How To Store State While Paginating Through Results - Laravel Inertia Vue

Is it possible to store the state of the select all checkbox or individual row checkbox while paginating through the results? As the props are passed on to the frontend through Inertia my paginator is requesting the pagination data and urls of the pages to paginate, from my props and then through Inertia link, navigating between the urls, it just seems to be like an spa, but it never stores the state of the rows selected or the select all checkbox. How can we overcome that?

select state

Apr
21
3 weeks ago
Activity icon

Started a new Conversation How Can I Use Handler _.throttle Function Within Watch Function In Vue 3 Composition API?

I have a reactive data object, filters. I need to watch for changes, whenever there is an update. I was successful to do so within Options API. But in the below use case, unable to make it work with Composition API. Here is the code piece below, please help me to convert it, so that its compatible with the setup() syntax. Please help me here.

filters: {
    handler: _.throttle(function() {
        let query = _.pickBy(this.filters);
        let route = this.route('users.index', Object.keys(query).length ? query : {
            remember: 'forget'
        });
        this.$inertia.get(route, {}, {
            only: ['usersData'],
            preserveState: true,
            preserveScroll: true
        });
    }, 300),
    deep: true,
},

I am able to format it according to the syntax required for Composition API, but unable to _.throttle, how can I format the above so that it works the same way with the Composition API? This is what I am doing right now, to log the response. But need to wrap the whole function within _.throttle.

watch(() => _.pickBy(filters), (currentValue, oldValue) => {
    console.log(currentValue);
    console.log(oldValue);
})
Apr
20
4 weeks ago
Activity icon

Started a new Conversation Unable To Pass The Required Parameters Into The URL - Laravel Inertia Vue

I am building a datatable with multi-column sorting functionality. As up to now, the sorting functionality is working fine, what I am unable to get is, right parameters into the url. As I am only passing $sorts to the component, hence I'm using this.$inertia.get to pass the $sorts back to the controller, which is returning back the sorted data. But due to passing sorts: this.sorts within the Inertia get method, its returning back the url query as http://127.0.0.1:8000/users?sorts[name]=asc. How can I get the required parameter within the Inertia get method so I get a url query as suchhttp://127.0.0.1:8000/users?sort_field=name&sort_direction=asc as well as pass the $sorts as well so it returns back the expected data.

sorting

Controller

public $sorts = [];

public function initalizeSortingRequest()
{
    $this->sorts = request()->get('sorts', $this->sorts);
}

public function applySorting($query)
{
    foreach ($this->sorts as $sort_field => $sort_direction) {
        $query->orderBy($sort_field, $sort_direction);
    }
        
    return $query;
}

Component

<script >
    methods: {
        sortBy(field) {
            if (!this.sorts[field]) {
                this.sorts[field] = 'asc';
            } else if (this.sorts[field] == 'asc') {
                this.sorts[field] = 'desc';
            } else {
                delete this.sorts[field];
            }

            let route = this.route('users.index', {
                sorts: this.sorts
            })
            this.$inertia.get(route, {}, {
                only: ['usersData'],
                preserveState: true,
                preserveScroll: true
            })
        }
    } 
</script>
Apr
18
1 month ago
Activity icon

Started a new Conversation Initialize Server Side Multi-column Sorting In Laravel Inertia Vue

I am trying to create server side sorting, in Laravel Inertia Vue. It will work as multi-column sorting , currently I am unable to imply it in the project. It was a matter of minutes, when was using Livewire stack. But, incase of Inertia Vue, unable to re-create it. Please help me someone! Waiting for the revert.

This is what I have done so far, This is what I have done so far,

Route

Route::put('/users/{column}', [UserController::class, 'sortBy'])->name('users.set-field');

Controller

class UserController extends Controller 
{
    public $sorts = [];

    public function index(Request $request) {
        $rowsQuery = User::query()->select('id', 'name', 'email', 'created_at')
                                  ->withRole();

        $rows = $this->applySorting($rowsQuery);

        return Inertia::render('Backend/Management/AudienceManagement/Users/Index', [
            'usersData' => $query,
            'sortingData' => $this->sorts
        ]);
    }

    public function sortBy($column) {
        if (! isset($this->sorts[$column])) return $this->sorts[$column] = 'asc';
        if ($this->sorts[$column] === 'asc') return $this->sorts[$column] = 'desc';
        unset($this->sorts[$column]);
    }

    public function applySorting($query) {
        foreach($this->sorts as $column => $direction) {
            $query->orderBy($column, $direction);
        }
        return $query;
    }
}

Component

<template>
    <!-- Data Table -->
    <data-table-base>
        <template #head>
            <data-table-heading class="pr-0">ID</data-table-heading>
            <data-table-heading sortable :direction="sorts['name'] ?? null" @click="sortBy('name')">Name</data-table-heading>
            <data-table-heading>Email</data-table-heading>
            <data-table-heading>Role</data-table-heading>
            <data-table-heading sortable :direction="sorts['created_at'] ?? null" @click="sortBy('created_at')">Date</data-table-heading>
        </template>
    </data-table-base>
</template>

<script>
    import DataTableBase from '@/Components/Custom/Table/Base'
    import DataTableHeading from '@/Components/Custom/Table/Heading'
    import axios from 'axios'

    export default {
        components: {
            DataTableBase,
            DataTableHeading
        },

        props: {
            usersData: {
                type: Object
            },
            sortingData: {
                type: Array
            }
        },

        data() {
            return {
                sorts: this.sortingData
            }
        },

        methods: {
            sortBy(column) {
                axios.put(this.route('users.set-field', {
                    column: column
                })).then((response) => {
                    console.log(response);
                });
            }
        }
    }
</script>

Is the above approach correct? Am I following in the right direction? If yes, how should I go ahead with it. Please help someone.

Apr
17
1 month ago
Activity icon

Replied to Want To Clean Up The Url Query Params On Certain Conditions - Laravel Inertia Vue

Where should I define the above it as I am paginating from the frontend?

Activity icon

Started a new Conversation Want To Clean Up The Url Query Params On Certain Conditions - Laravel Inertia Vue

Currently I am fetching and paginating the data and it is all seamless, works great, but I need to set a certain condition, one of such condition is when the user is on 1st page or when he has paginated back to the first page, I need to clear the parameter at that point i.e. from http://127.0.0.1:8000/users?page=1 to http://127.0.0.1:8000/users.

Something like Caleb has been using in withPagination trait, in Livewire.

    public $page = 1;

    public function getQueryString()
    {
        return array_merge(['page' => ['except' => 1]], $this->queryString);
    }

How that can be attained with my current approach? Please throw some light on here. Thanks already!

Activity icon

Started a new Conversation [Laravel Inertia Vue] How Can I Put A Value To A Session Key As Well As Apply That As Parameter At The Same Time?

Currently I am successfully able to store the session through axios by posting the value to an endpoint. The perPage variable picks the value from the session, if it exists, other wise set it to the default value, i.e. 5. Its all working as it should, I just wanted to know is it possible to store the session as I was doing by posting it to an endpoint as well as apply that as a parameter in the url too?

As before the session approach, i.e. instead of storing the value in the session, I was implementing this.$inertia.get(this.route('users.index', { per_page: this.per_page }), {}, { preserveState: true, preserveScroll: true }) but I want both the approaches working hand in hand, i.e. store the value in the session key perPage as well as add a parameter to the url as the value changes in the session key.

enter image description here

Route

Route::put('/set-per-page', [UserController::class, 'updatePerPage'])->name('set.per_page');

Controller

class UserController extends Controller
{
    public $perPage = 5;

    public function __construct()
    {
        $this->middleware(function ($request, $next) 
        {
            $this->perPage = session()->get('perPage', $this->perPage);
            return $next($request);
        });
    }

    public function updatePerPage(Request $request)
    {
        session()->put('perPage', (int)$request->get('per_page'));
        
        return session('perPage');
    }
}

Component

<template>
    <input-group inline>
        <input-select v-model="per_page" placeholder="Per Page">
            <option value="5">5</option>
            <option value="10">10</option>
        </input-select>
    </input-group>
</template>

<script>
    export default {
        props: {
            perPageData: {
                type: Number
            }
        },

        data() {
            return {
                per_page: this.perPageData
            }
        },

        watch: {
            perPage: {
                handler: function() {
                    axios.put(route('set.per_page', { per_page: this.per_page })).then((response)=>{ this.$inertia.reload({ only: ['usersData'] }), console.log(response) })
                }
            }
        }
    }
</script>
Activity icon

Replied to Why The Session Is Storing Key Data As A String Instead Of Number - Laravel Inertia Vue

The code I posted above with (int)$request->get('per_page') within the public function updatePerPage worked as a charm, thanks a lot for directing me to the right path!

Activity icon

Replied to Why The Session Is Storing Key Data As A String Instead Of Number - Laravel Inertia Vue

Thanks for the revert! Please can you explain how can I do that, down below is my current implementation of storing a value in the session whenever the value in the frontend changes.

public function updatePerPage(Request $request)
{
    session()->put('perPage', (int)$request->get('per_page'));
        
    return session('perPage');
}
Apr
16
1 month ago
Activity icon

Started a new Conversation Why The Session Is Storing Key Data As A String Instead Of Number - Laravel Inertia Vue

I am currently storing perPage data in the sessions and partially loading the data based on the perPage value selected. The problem is, I have set my prop type as number, but when the perPage data is being stored in the sessions, it is being stored as a string. So it is throwing me an error in the console log.

Invalid prop: type check failed for prop "perPageData". Expected Number with value 10, got String with value "10".

How can I store the value in the sessions as a number and not a string? Help would be really grateful.

Activity icon

Awarded Best Reply on Unable To Put Session In Laravel Vue Using Axios

@wakanda The actual problem was, we cant use sessions() within public function __construct() so it was unable to get the value from the session. As per the current setup, with a minor work around the problem was solved.

Using an inline middleware, we can hook into the request's routing, so that we have full access to the session.

public function __construct()
{
    $this->middleware(function ($request, $next) {

        $this->perPage = session()->get('perPage', $this->perPage);

        return $next($request);
    });
}
Activity icon

Replied to Unable To Put Session In Laravel Vue Using Axios

@wakanda The actual problem was, we cant use sessions() within public function __construct() so it was unable to get the value from the session. As per the current setup, with a minor work around the problem was solved.

Using an inline middleware, we can hook into the request's routing, so that we have full access to the session.

public function __construct()
{
    $this->middleware(function ($request, $next) {

        $this->perPage = session()->get('perPage', $this->perPage);

        return $next($request);
    });
}
Activity icon

Replied to Unable To Put Session In Laravel Vue Using Axios

I tried your method, Its doing nothing, and when I remove the default value and just construct it with $this->perPage = session()->get('perPage'), the pagination is destroyed as there is no perPage value in the session, but then I update it through the setPerPage() public method, as the construct method will be receiving the key value of perPage, still the pagination is destroyed, that means setPerPage method isn't actually setting the session, other wise it would have been accessed by the construct method. I am still thinking why this kind of behavior is happening?

Activity icon

Replied to Unable To Put Session In Laravel Vue Using Axios

By mistakenly I clicked on the best answer, what argument do I need to pass within $this->index()? like how should I format it?

Activity icon

Replied to Unable To Put Session In Laravel Vue Using Axios

With $this->index() getting an exception

"ArgumentCountError"

and getting the following message within the network tab.

"App\Http\Controllers\Backend\Management\AudienceManagement\UserController::index(), 0 passed in C:\xampp\htdocs\InertiaVue\app\Http\Controllers\Backend\Management\AudienceManagement\UserController.php on line 45 and exactly 1 expected"

Activity icon

Replied to Unable To Put Session In Laravel Vue Using Axios

@wakanda Is this the correct way of implementation for the above objective? What can be done to make it work, as I see there are no mistakes so far!

Activity icon

Replied to Unable To Put Session In Laravel Vue Using Axios

Mate I really appreciate your efforts, thanks a ton for that! But still its the same, what I am seeking for is as the perPage value changes, the data should be paginated to the value selected as well as the perPage select input should show the value which the user selected, but even after session being created, the construct method is unable to take the value form the key perPage so by default 5 value is being assigned. Where the error lies, just not able to point.

Activity icon

Replied to Unable To Put Session In Laravel Vue Using Axios

Thanks for your revert! Okay, so when I dd(session('perPage')); I am getting the value 10 as when I update it to 10 from the frontend. But when I reload the page it should pick the new perPage value as a session for it exists. And in my controller I have defined perPage as a public property and within the __construct() method I am defining $this->perPage = session()->get('perPage', $this->perPage); and passing the perPage as a data prop to the frontend, but still the perPage value reverts back to 5 which is the default value. Here is my complete controller for reference. Any idea why such kind of behavior is happening?

enter image description here

Controller

{
    public $perPage = 5;

    public function __construct()
    {
        $this->perPage = session()->get('perPage', $this->perPage);
    }

    public function index(Request $request)
    {
        $filters = $request->all('search');

        $rowsQuery = User::query()
                    ->select('id', 'name', 'email', 'role_id', 'created_at')
                    ->withRole()
                    ->filter($request->only('search'))
                    ->paginate($this->perPage)
                    ->withQueryString();

        return Inertia::render('Backend/Management/AudienceManagement/Users/Index', [
            'filtersData' => $filters,
            'usersData' => $rowsQuery,
            'perPageData' => $this->perPage
        ]);
    }

    public function setPerPage(Request $request)
    {
        session()->put('perPage', $request->perPage);

        dd(session('perPage'));
        
        return session('perPage');
    }
}
Activity icon

Replied to Unable To Put Session In Laravel Vue Using Axios

Okay, so when I set the perPage to 10, this is what I get in the preview.

array:1 [
  "perPage" => "10"
]

What can be the issue, why the session key with value isn't being updated or created? Please help me here, need to learn and rectify this part, as many things in my application depends on this :(

Activity icon

Replied to Unable To Put Session In Laravel Vue Using Axios

When I am doing dd, there is no response on the screen and also the response in the console log also contains no data.

enter image description here

But when I omit dd, I get the data in the response in the console log

enter image description here

Activity icon

Replied to Unable To Put Session In Laravel Vue Using Axios

I think it doesn't really matters using $request->session() or just session(), because its still operating the same way.

Activity icon

Started a new Conversation Unable To Put Session In Laravel Vue Using Axios

I am trying to create an endpoint and send the data to then endpoint and requesting it later within the controller method. As the input value changes, it fires axios put method and pass the updated perPage data to an endpoint, I am getting a successful response, with status 200 in the console log, but the value isn't being updated or created in the sessions. I just don't know what am I missing here. Please throw some light here. Thanks!

Web

Route::put('/set-per-page', [UserController::class, 'setPerPage'])->name('set.per_page');

Controller

public function setPerPage(Request $request)
{
    $request->session()->put('perPage', $request->perPage);
    return session('perPage');
}

Component

<template>
    <input-group inline>
        <input-select v-model="perPage" placeholder="Per Page">
            <option value="5">5</option>
            <option value="10">10</option>
        </input-select>
    </input-group>
</template>

<script>
    export default {
        props: {
            perPageData: {
                type: Number
            }
        },

        data() {
            return {
                perPage: this.perPageData
            }
        },

        watch: {
            perPage: {
                handler: function() {
                    axios.put(route('set.per_page', { perPage: this.perPage })).then((response)=>{ console.log(response) })
                }
            }
        }
    }
</script>
Apr
10
1 month ago
Activity icon

Started a new Conversation How Can I Update Laravel Session Data Using Inertia Vue?

I have recently migrated from Laravel Livewire to Laravel Inertia Vue. During the course while using Livewire, I created a trait called WithPerPagePagination then created a public variable of perPage with the default value of 10 and mounted the value to the session $this->perPage = session()->get('perPage', $this->perPage);. Then with the help of lifecycle hook, created a function method updatedPerPage($value) now when ever the perPage variable is updated the value will be passed into the session using session()->put('perPage', $value); and then finally applying the pagination to the query return $query->paginate($this->perPage);. The perPage variable is wire modeled to the select input in the blade frontend.

WithPerPagePagination Trait

trait WithPerPagePagination
{
    use WithPagination;

    public $perPage = 10;

    public function mountWithPerPagePagination()
    {
        $this->perPage = session()->get('perPage', $this->perPage);
    }

    public function updatedPerPage($value)
    {
        session()->put('perPage', $value);
    }

    public function applyPagination($query)
    {
        return $query->paginate($this->perPage);
    }
}

Now in the case of Inertia Vue, how can I put the updated value of per_page into the session, from the frontend and get the above behavior. Now for the Inertia Vue application, I have defined a per_page variable within the index method, $request->has('per_page') ? $request->per_page : 5; and using it within the query as in paginate($per_page) and passing it as a prop, to the frontend. Later in the frontend, initializing the prop per_page with the type Number, and creating and returning data, paginate: { per_page: this.per_page }, then creating a method initPerPage() returning this.$inertia.replace(route('users.index', { per_page: this.paginate.per_page })). And finally, v-modeling to paginate.per_page and if whenever there is a change, run initPerPage. This method replaces the url of the route with the desired per_page value selected.

User Controller

public function index(Request $request)
{
    $per_page = $request->has('per_page') ? $request->per_page : 5;
    $users =  User::query()
                ->select('id', 'name', 'email', 'role_id', 'created_at')
                ->when($request->search, fn($query, $search) => $query->where('name', 'like', '%'.$search.'%'))
                ->paginate($per_page)
                ->withQueryString();

    return Inertia::render('Backend/Management/AudienceManagement/Users/Index', [
        'per_page' => $per_page,
        'users' => $users
    ]);
}

User Index Vue

<template>
    <input-group inline>
        <input-select v-model="paginate.per_page" @change="initPerPage" placeholder="Per Page">
            <option value="5">5</option>
            <option value="10">10</option>
        </input-select>
    </input-group>
</template>

<script>
    import InputGroup from '@/Components/Custom/Input/Group'
    import InputSelect from '@/Components/Custom/Input/Select'

    export default {
        components: {
            InputGroup,
            InputSelect
        },
        props : {
            per_page: {
                type: Number
            }
        },
        data() {
            return {
                paginate: {
                    per_page: this.per_page
                }
            }
        },
        methods: {
            initPerPage() {
                this.$inertia.replace(route('users.index', { per_page: this.paginate.per_page }))
            }
        }
    }
</script>

Now with my current Inertia Vue approach, as soon as the user changes the per_page select input, the selected value will be added with the parameter per_page=value to the url, which makes it work, but as the per_page value is not stored into the session, whenever I refresh the page, or redirect back to the page, the per_page value is back to default. Please help me here to create the same behavior as in Livewire. Thank you for your time.

Apr
05
1 month ago
Activity icon

Replied to Unable To Update Per Page Count From The Frontend (Laravel, InertiaJS, VueJS)

Please help me with an example, I just don't know from where should I start. Your help we be really valued. Thank you for your time.

Apr
04
1 month ago
Activity icon

Replied to Unable To Update Per Page Count From The Frontend (Laravel, InertiaJS, VueJS)

Thanks for the revert @bobbybouwmann. In my Livewire project I used the session method to update the per page and added a lifecycle hook on the per page variable, as soon as the value will be updated, put the per page value in the sessions.

trait WithPerPagePagination
{
    use WithPagination;

    public $perPage = 10;

    public function mountWithPerPagePagination()
    {
        $this->perPage = session()->get('perPage', $this->perPage);
    }

    public function updatedPerPage($value)
    {
        session()->put('perPage', $value);
    }

    public function applyPagination($query)
    {
        return $query->paginate($this->perPage);
    }
}

Here is my updated code down below. I am trying to replicate the same above function in Laravel, Inertia, Vue. I have created a public variable for $perPage with a default value of 5. What I need to do now is, I need to link it to the drop down input. And after that as soon as I change the per page value, it should put the per page value in the session as I had done it in the previous project using session()->put('perPage', $value);

Class UserController extends Controller
{
    public $perPage = 5;

    public function index()
    {
        $this->perPage = session()->get('perPage', $this->perPage);

        $query = User::select('id', 'name', 'email', 'role_id', 'created_at');
        $users = $query->paginate($this->perPage);

        return Inertia::render('Backend/Management/AudienceManagement/Users/Index', [
            'users' => $users
        ]);
    }
}
Activity icon

Started a new Conversation Unable To Update Per Page Count From The Frontend (Laravel, InertiaJS, VueJS)

I am migrating my current application from Laravel Livewire to Laravel InertiaJS VueJS. Currently I am stuck at setting the per page count from the front end and paginate the data accordingly. Currently I am using Laravel's default pagination along with the custom pagination component for VueJS and it works seamlessly. I just want to set the $per_page as per the input, the variable is set to 5 by default, in the index method of the controller. Below is the code structure and the logic. Please help me achieve this in the way InertiaJS is meant to be used.

enter image description here

UserController.php

    public function index(Request $request)
    {
        $per_page = \Request::get('per_page') ?: 5;

        $query = User::select('id', 'name', 'email', 'role_id', 'created_at');
        $users = $query->paginate($per_page);

        return Inertia::render('Backend/Management/AudienceManagement/Users/Index', [
            'users' => $users
        ]);
    }

Users/Index.vue

<template>
    <input-group borderless paddingless inline>
        <input-select @change="setPerPage($event)" id="perPage" placeholder="Per Page">
            <option value="5">5</option>
            <option value="10">10</option>
        </input-select>
    </input-group>
</template>

<script>
    import {
        Inertia
    } from '@inertiajs/inertia'

    export default {
        props: {
            users: {
                type: Object
            }
        },
        data() {
            return {
                sortField: '',
                sortDirection: ''
            }
        },
        methods: {
            setPerPage(event) {
                console.log(event.target.value);
                this.users.per_page = event.target.value;
                Inertia.reload({
                    only: ['users.data']
                });
            },
        }
    }
</script>
Jan
31
3 months ago
Activity icon

Replied to How Can I Use A Blade Directive Within The Livewire Wire:click Template Directive?

@snapey I guess, its converting php variable to javascript, so it can be accessed. By using json_encode the content doesn't escapes. Do you have any better solution?

Jan
30
3 months ago
Activity icon

Replied to How Can I Use A Blade Directive Within The Livewire Wire:click Template Directive?

@snapey When I was referring to the error, I was talking wire:click="$emit('deleteUserBulk', {{ $selected }} ". And I tried your above approach, now to check what rows have being selected, I added @json($selected) to the child component blade to check for the ids which were passed to the component. And here is the output from the blade. When I use {{ json_encode($selected) }} without single quotes, it shows the ids, but thorugh your approach its giving me some weird output.

[\u00221\u0022,\u00222\u0022,\u00223\u0022,\u00224\u0022,\u00225\u0022]

Activity icon

Replied to How Can I Use A Blade Directive Within The Livewire Wire:click Template Directive?

Its in a trait which is used in both, parent component as well as the child component. So the items selected in parent component will be passed to the child component.

Activity icon

Replied to How Can I Use A Blade Directive Within The Livewire Wire:click Template Directive?

In the past it was throwing me an error, so I used json_encode. When I select the items one by one instead of select all I get the following error.

htmlspecialchars() expects parameter 1 to be string, array given (View: C:\xampp\htdocs\Management\resources\views\livewire\backend\management\audience-management\user-controller.blade.php)

But when I am using json_encode, no such error. What can be the problem, according to you?

Activity icon

Started a new Conversation How Can I Use A Blade Directive Within The Livewire Wire:click Template Directive?

I am currently on Laravel 8 with Livewire. I know it may sound a bit noob but please help me substituting @json instead of json_encode within the livewire template directive i.e. wire:click.

Here is the whole line of code for follwing.

wire:click="$emit('deleteUserBulk', {{ json_encode($selected) }} )"
Jan
29
3 months ago
Activity icon

Started a new Conversation Why Mount Lifecycle Hook Has Been Mounting All The Rows With Its 'id' Which Has Been Selected And Has Ever Been Passed To The Child Component?

Description

I have two components, one parent and one child. I am passing the id of number of rows selected from the parent component to the child component. And in the child component I am using mount() lifecycle hook to pass the selected ids to the child component and later on display the confirmation modal to delete the number of rows selected.

At first when the parent component renders for the first time along with the child component, I select the rows and pass it to the child component. The child component is a modal, which asks the user to confirm the action and delete the selected number of rows with the passed id.

The problem is even after I delete the selected number of rows when the component loads for the first time. The selected number of rows with their id which were deleted are still mounted to the component, even after being deleted. How can I overcome this issue, please help me?

Exact steps to reproduce

enter image description here

Stripped-down, copy-pastable code snippets

  • Livewire/Traits/WithBulkActions
trait WithBulkActions
{
    public $selectPage = false;
    public $selectAll = false;
    public $selected = [];

    public function renderingWithBulkActions()
    {
        if ($this->selectAll) $this->selectPageRows();
    }

    public function updatedSelected()
    {
        $this->selectAll = false;
        $this->selectPage = false;
    }

    public function updatedSelectPage($value)
    {
        if ($value) return $this->selectPageRows();

        $this->selectAll = false;
        $this->selected = [];
    }

    public function selectPageRows()
    {
        $this->selected = $this->rows->pluck('id')->map(fn($id) => (string) $id);
    }

    public function selectAll()
    {
        $this->selectAll = true;
    }

    public function getSelectedRowsQueryProperty()
    {
        return (clone $this->rowsQuery)
            ->unless($this->selectAll, fn($query) => $query->whereKey($this->selected));
    }
}
  • Livewire/ChildComponent
class UserBulkDeletion extends Component
{
    use WithCachedRows, WithSorting, WithBulkActions, WithPerPagePagination;
    
    public User $user;
    public $showUserBulkDeletionModal = false;
    public $filters = [
        'search' => "",
        'email' => null,
        'role' => '',
        'date-min' => null,
        'date-max' => null,
    ];

    protected $listeners = ['deleteUserBulk'];

    public function mount($selected)
    {
        $this->selected = $selected;
    }

    public function deleteUserBulk()
    {
        $this->useCachedRows();

        $this->showUserBulkDeletionModal = true;
    }

    public function confirmDeleteBulk()
    {
        $deleteCount = $this->selectedRowsQuery->count();

        $this->selectedRowsQuery->delete();
        $this->showUserBulkDeletionModal = false;

        $this->notify(($deleteCount <= 1) ? 'You\'ve deleted '.$deleteCount.' user' : 'You\'ve deleted '.$deleteCount.' users');
        $this->emit('sectionRefresh');
    }

    public function getRowsQueryProperty()
    {
        $query = User::query()
            ->select('id')
            ->when($this->filters['search'], fn($query, $search) => $query->where('name', 'like', '%'.$search.'%'))
            ->when($this->filters['email'], fn($query, $email) => $query->where('email', 'like', '%'.$email.'%'))
            ->when($this->filters['role'], fn($query, $role) => $query->where('role_id', $role))
            ->when($this->filters['date-min'], fn($query, $created_at) => $query->where('created_at', '>=', Carbon::createFromFormat('d/m/Y', $created_at)))
            ->when($this->filters['date-max'], fn($query, $created_at) => $query->where('created_at', '<=', Carbon::createFromFormat('d/m/Y', $created_at)));
        
        return $this->applySorting($query);
    }

    public function getRowsProperty()
    {
        return $this->cache(function () {
            return $this->applyPagination($this->rowsQuery);
        });
    }

    public function render()
    {
        return view('livewire.backend.management.audience-management.logical-component.user-bulk-deletion', ['users' => $this->rows]);
    }
}
  • ParentComponent Blade
@if ($selected)
<x-dropdown label="Bulk Actions">
    <x-dropdown.item type="button" wire:click="$emit('deleteUserBulk')" class="flex items-center space-x-2">
        <x-icon.trash class="text-cool-gray-400"/> <span>Delete</span>
    </x-dropdown.item>
</x-dropdown>
@endif
  • ChildComponent Blade
<div>
    <form wire:submit.prevent="confirmDeleteBulk">
        <x-modal.confirmation wire:model.defer="showUserBulkDeletionModal">
            <x-slot name="title">Delete User</x-slot>

            <x-slot name="content">
                @json($selected)
                Are you sure you want to delete users? This action is irreversible!
            </x-slot>

            <x-slot name="footer">
                <x-button.secondary wire:click="$set('showUserBulkDeletionModal', false)">Cancel</x-button.primary>

                <x-button.primary type="submit">Delete</x-button.primary>
            </x-slot>
        </x-modal.confirmation>
    </form>
</div>

Context

  • Livewire version: 2.3.8
  • Laravel version: 8.25.0
  • Alpine version: 2.8.0
  • Browser: Chrome
Activity icon

Replied to Unable To Associate Role To A User For One To Many Relationship

Actually, when I was mounting the role input for the modal component, I had called for $this->role = $user->role()->pluck('id') which was causing the problem, as it was passing the ids as an array. As I am type hinting model properties, here is my approach which I just implied.

Its working now as I wanted it to be. Thanks for your time and effort. :)

  • User Controller
    public User $user;

    protected $listeners = ['updateUser'];

    protected $rules = [
        'user.name' => 'required|string|max:255',
        'user.email' => 'required|string|email|max:255',
        'user.role_id' => 'required',
    ];

    public function updateUser(User $user)
    {
        $this->useCachedRows();
        $this->resetValidation();
    
        $this->user = $user;
        $this->showUserUpdationModal = true;
    }

    public function storeUser()
    {
        $this->validate();
        $this->validate([
            'user.email' => 'unique:users,email,'.$this->user->id,
        ]);
        $this->user->role()->associate($this->user->role_id);
        $this->user->save();
        $this->showUserUpdationModal = false;

        $this->dispatchBrowserEvent('notify', $this->user->name.' Updated Successfully');
        $this->emit('sectionRefresh');
    }
Activity icon

Replied to Unable To Associate Role To A User For One To Many Relationship

Yes mate, surely. I have updated the user controller code block as well, as I have added the public function updateUser method which mounts the user and his role as well.

  • User Update Modal Blade Component
<div>
    <form wire:submit.prevent="storeUser">
        @csrf
        <x-modal.dialog wire:model.defer="showUserUpdationModal">
            <x-slot name="title">Update User</x-slot>
            <x-slot name="content">
                <x-input.group for="name" label="Name" :error="$errors->first('user.name')">
                    <x-input.text wire:model="user.name" type="text" id="name" placeholder="Enter Name" />
                </x-input.group>
                <x-input.group for="email" label="Email" :error="$errors->first('user.email')">
                    <x-input.text wire:model="user.email" type="email" id="email" placeholder="Enter Email" />
                </x-input.group>
                <x-input.group for="role" label="Role" :error="$errors->first('role')">
                    <x-input.select wire:model="role" id="role">
                        @foreach ($roles as $role)
                            <option value="{{ $role->id }}">{{ $role->name }}</option>
                        @endforeach
                    </x-input.select>
                </x-input.group>
            </x-slot>
            <x-slot name="footer">
                <x-button.secondary wire:click="$set('showUserUpdationModal', false)">Cancel</x-button.secondary>
                <x-button.primary type="submit">Save</x-button.primary>
            </x-slot>
        </x-modal.dialog>
    </form>
</div>
  • User Controller
public $showUserUpdationModal = false;
public $role;
public User $user;

protected $rules = [
    'user.name' => 'required|string|max:255',
    'user.email' => 'required|string|email|max:255',
    'role' => 'required',
];

public function updateUser(User $user)
{
    $this->resetValidation();
        
    $this->user = $user;
    $this->role = $user->role()->pluck('id');
    $this->showUserUpdationModal = true;
}

public function storeUser()
{
    $this->validate();
    $this->validate([
        'user.email' => 'unique:users,email,'.$this->user->id,
    ]);
    $this->user->role()->associate($this->role);
    $this->user->save();
    $this->showUserUpdationModal = false;

    $this->dispatchBrowserEvent('notify', $this->user->name.' Updated Successfully');
    $this->emit('sectionRefresh');
}
Jan
28
3 months ago
Activity icon

Replied to Unable To Associate Role To A User For One To Many Relationship

@frankielee Mate, when I'm doing that, I'm getting the following error.

SQLSTATE[22007]: Invalid datetime format: 1366 Incorrect integer value: '[2]' for column management.users.role_id at row 1 (SQL: update users set role_id = [2], users.updated_at = 2021-01-29 04:30:07 where id = 2)

What can be this about, please help me here.

Activity icon

Started a new Conversation Unable To Associate Role To A User For One To Many Relationship

I have a one to many relationship between users and roles. I am unable to associate a role to a user while saving or updating a user. Please spare some time to have a look below. Thank you for your time.

  • Database Structure
Users
----------
* id
* name
* email
* password
* role_id
* created_at

Roles
----------
* id
* name
* slug
* created_at
  • User Model
public function role() {
    return $this->belongsTo(Role::class);
}
  • Role Model
public function users() {
    return $this->hasMany(User::class);
}
  • User Controller
public $showUserUpdationModal = false;
public $role;
public User $user;

protected $rules = [
    'user.name' => 'required|string|max:255',
    'user.email' => 'required|string|email|max:255',
    'role' => 'required',
];

public function storeUser()
{
    $this->validate();
    $this->validate([
        'user.email' => 'unique:users,email,'.$this->user->id,
    ]);
    $this->user->save();
    $this->user->role()->associate($this->role);
    $this->showUserUpdationModal = false;

    $this->dispatchBrowserEvent('notify', $this->user->name.' Updated Successfully');
    $this->emit('sectionRefresh');
}
Activity icon

Replied to How Can I Check If The User Has A Role For One To One Relationship?

@michaloravec I need to check if the user who is logging in is either an administrator or an employee, and if yes redirect to the specified route. But I am unable to do so with the following code. Please throw some light on this if you can?

  • Models/User
public function hasAnyRoles(array $roles) 
{
    if ($this->role()->whereIn('name', $roles)->first()) {
        return true;
    }
    return false;
}
  • Responses/LoginResponse
public function toResponse($request)
{
    if(Auth::user()->hasAnyRoles(['administrator', 'employee'])) {
        return redirect()->route('backend.dashboard');
    }

    return redirect()->route('frontend.dashboard');
}
Activity icon

Awarded Best Reply on How Can I Check If The User Has A Role For One To One Relationship?

That wasn't the issue, the main issue lies in the relationship, as I have defined it inversely. I need to invert the relation. User has 1 role, Role has many Users

Role:

public function users() 
{
    return $this->hasMany(User::class);
}

User:

public function role() 
{
    return $this->belongsTo(Role::class);
}

It's a One To Many relation. Just re defining the relation fixed the issue. Thanks for your time. :)

Activity icon

Replied to How Can I Check If The User Has A Role For One To One Relationship?

That wasn't the issue, the main issue lies in the relationship, as I have defined it inversely. I need to invert the relation. User has 1 role, Role has many Users

Role:

public function users() 
{
    return $this->hasMany(User::class);
}

User:

public function role() 
{
    return $this->belongsTo(Role::class);
}

It's a One To Many relation. Just re defining the relation fixed the issue. Thanks for your time. :)

Activity icon

Started a new Conversation How Can I Check If The User Has A Role For One To One Relationship?

I have an application with User and Role model and a one to one relationship between them. How can I check if the user has a role. I am getting an SQLSTATE[42S22] error.

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'roles.user_id' in 'where clause' (SQL: select * from roles where roles.user_id = 1 and roles.user_id is not null and name = client limit 1)

  • App/Models/User
public function role() 
{
    return $this->hasOne(Role::class);
}

public function hasRole(string $role) 
{
    if ($this->role()->where('name', $role)->first()) {
        return true;
    }
    return false;
}
  • App/Models/Role
public function users() 
{
    return $this->belongsTo(User::class);
}
Jan
27
3 months ago
Activity icon

Started a new Conversation Dynamic Relationships In Laravel Using Subqueries For Belongstomany Relationship

As I have been following Eloquent Performance Patterns by Jonathan Reinink, he has explained how to add dynamic relationship using subquery for models with hasmany relationship. But as per my application I need to do the same for belongstomany relationship. Please help me achieve it.

Here is the example source code of the following, which achieves the said above dynamic relationship using subquery for models with hasmany relationship.

$query = User::query()
    ->addSelect(['role' => Role::select('name')
        ->whereColumn('user_id', 'users.id')
        ->latest()
        ->take(1)
    ]);
        
return $this->applySorting($query);
Jan
25
3 months ago
Activity icon

Started a new Conversation How A Public Property, Which Is Defined In A Trait, And Used In A Component Can Be Passed To A Nested Component Which Is Using The Same Trait?

Description

How an array of selected users assigned to a public property i.e. $selected = [], which is defined in a trait i.e. WithBulkActions and used in the component i.e. UserController, can be passed to a nested component i.e. UserBulkDeletion which is using the same trait i.e. WithBulkActions?

1

Application structure

  1. App\Http\Livewire
    • Component
      • UserController - App/Http/Livewire/Backend/UserManagement/UserController
      • UserBulkDeletion - App/Http/Livewire/Backend/UserManagement/LogicalComponent/UserBulkDeletion
    • Trait
      • WithBulkActions - App/Http/Livewire/Traits/WithBulkActions

Stripped-down, copy-pastable code snippets

  • UserController
class UserController extends Component
{
    use WithCachedRows, WithSorting, WithBulkActions, WithPerPagePagination;

    public User $user;
    public $showFilters = false;
    public $filters = [
        'search' => "",
        'email' => null,
        'role' => '',
        'date-min' => null,
        'date-max' => null,
    ];

    protected $listeners = ['sectionRefresh' => '$refresh'];

    public function toggleShowFilters()
    {
        $this->useCachedRows();

        $this->showFilters = ! $this->showFilters;
    }

    public function resetFilters() 
    {
        $this->reset('filters'); 
    }

    public function updatedFilters() 
    {
        $this->resetPage();
    }
    
    public function getRowsQueryProperty()
    {
        $query = User::query()
            ->when($this->filters['email'], fn($query, $email) => $query->where('email', 'like', '%'.$email.'%'))
            ->when($this->filters['role'], fn($query, $role) => $query->whereHas('roles', fn ($query) => $query->where('id', $role)))
            ->when($this->filters['search'], fn($query, $search) => $query->where('name', 'like', '%'.$search.'%'))
            ->when($this->filters['date-min'], fn($query, $created_at) => $query->where('created_at', '>=', Carbon::createFromFormat('d/m/Y', $created_at)))
            ->when($this->filters['date-max'], fn($query, $created_at) => $query->where('created_at', '<=', Carbon::createFromFormat('d/m/Y', $created_at)));
        
        return $this->applySorting($query);
    }

    public function getRowsProperty()
    {
        return $this->cache(function () {
            return $this->applyPagination($this->rowsQuery);
        });
    }

    public function getRolesProperty()
    {
        $roles = Role::all();
        return $roles;
    }
    
    public function render()
    {
        return view('livewire.backend.management.audience-management.user-controller', ['users' => $this->rows, 'roles' => $this->roles]);
    }
}
  • UserBulkDeletion
class UserBulkDeletion extends Component
{
    use WithCachedRows, WithBulkActions, WithSorting;
    
    public $showUserBulkDeletionModal = false;
    public User $user;
    public $filters = [
        'search' => "",
        'email' => null,
        'role' => '',
        'date-min' => null,
        'date-max' => null,
    ];

    protected $listeners = ['deleteUserBulk'];

    public function deleteUserBulk()
    {
        $this->useCachedRows();

        $this->showUserBulkDeletionModal = true;
    }

    public function confirmDeleteBulk()
    {
        $deleteCount = $this->selectedRowsQuery->count();
        
        foreach ($this->selectedRowsQuery->get() as $queryRow) {
            $queryRow->roles()->detach();
        }

        $this->selectedRowsQuery->delete();
        $this->showUserBulkDeletionModal = false;

        $this->notify('You\'ve deleted '.$deleteCount.' users');
        $this->emit('sectionRefresh');
    }

    public function getRowsQueryProperty()
    {
        $query = User::query()
            ->when($this->filters['email'], fn($query, $email) => $query->where('email', 'like', '%'.$email.'%'))
            ->when($this->filters['role'], fn($query, $role) => $query->whereHas('roles', fn ($query) => $query->where('id', $role)))
            ->when($this->filters['search'], fn($query, $search) => $query->where('name', 'like', '%'.$search.'%'))
            ->when($this->filters['date-min'], fn($query, $created_at) => $query->where('created_at', '>=', Carbon::createFromFormat('d/m/Y', $created_at)))
            ->when($this->filters['date-max'], fn($query, $created_at) => $query->where('created_at', '<=', Carbon::createFromFormat('d/m/Y', $created_at)));
        
        return $this->applySorting($query);
    }

    public function render()
    {
        return view('livewire.backend.management.audience-management.logical-component.user-bulk-deletion');
    }
}
  • WithBulkActions
trait WithBulkActions
{
    public $selectPage = false;
    public $selectAll = false;
    public $selected = [];

    public function renderingWithBulkActions()
    {
        if ($this->selectAll) $this->selectPageRows();
    }

    public function updatedSelected()
    {
        $this->selectAll = false;
        $this->selectPage = false;
    }

    public function updatedSelectPage($value)
    {
        if ($value) return $this->selectPageRows();

        $this->selectAll = false;
        $this->selected = [];
    }

    public function selectPageRows()
    {
        $this->selected = $this->rows->pluck('id')->map(fn($id) => (string) $id);
    }

    public function selectAll()
    {
        $this->selectAll = true;
    }

    public function getSelectedRowsQueryProperty()
    {
        return (clone $this->rowsQuery)
            ->unless($this->selectAll, fn($query) => $query->whereKey($this->selected));
    }
}

Context

  • Livewire version: 2.3.8
  • Laravel version: 8.24.0
  • Alpine version: 2.8.0
  • Browser: Chrome
Jan
24
3 months ago
Activity icon

Started a new Conversation Unable To Pass An Array Of Selected Data From Parent Component With Traits To The Nested Component

Application Structure

  • App/Http/Livewire
  1. UserController - Livewire/UserManagement/UserController
  2. WithBulkActions - Livewire/Traits/DataTable/WithBulkActions
  • resources/views/livewire
  1. UserController Blade - livewire/user-management/user-controller

Description

I am creating a CRUD system, with bulk actions to delete the selected data. I have extracted the logic which is responsible to select multiple items or to select all items in the current data table i.e UserController, so I can use it as a trait i.e. WithBulkActions, in other data table components. The trait is only responsible to select multiple items or to select all items from the data table. The public function method to delete an array of data, is present in the data table component controller itself i.e. UserController. Now, to make the multiple select with bulk actions work, I have to include the confirmation modal, which is responsible to fire the method to delete an array of data, in the data table component blade view i.e. UserController Blade. It works perfectly when I include the confirmation modal to delete the selected data inside the user controller. While each row has a checkbox modeled to wire:model="selected" with the value="{{ $user->id }}" within the foreach loop. The public variable selected is initialized as public $selected = []; within the trait, WithBulkActions and then the trait is being used in the component, UserController.

rowsQuery property within the UserController component gets the data from the User model in a query with the filters, sorting and return it as a property.

public function getRowsQueryProperty()
    {
        $query = User::query()
            ->when($this->filters['email'], fn($query, $email) => $query->where('email', 'like', '%'.$email.'%'))
            ->when($this->filters['role'], fn($query, $role) => $query->whereHas('roles', fn ($query) => $query->where('id', $role)))
            ->when($this->filters['search'], fn($query, $search) => $query->where('name', 'like', '%'.$search.'%'))
            ->when($this->filters['date-min'], fn($query, $created_at) => $query->where('created_at', '>=', Carbon::createFromFormat('d/m/Y', $created_at)))
            ->when($this->filters['date-max'], fn($query, $created_at) => $query->where('created_at', '<=', Carbon::createFromFormat('d/m/Y', $created_at)));
        
        return $this->applySorting($query);
    }

Then the rowsQuery is cloned in the selectedRowsQuery property within the trait, WithBulkActions.

public function getSelectedRowsQueryProperty()
    {
        return (clone $this->rowsQuery)
            ->unless($this->selectAll, fn($query) => $query->whereKey($this->selected));
    }

If incase an array of data is being selected and the selected data should be deleted, the public function confirmDeleteBulk() is responsible for it, which is in UserController component, the following public function calls for selectedRowsQuery property, which is initialized in the trait itself, and then it executes the delete() method and notify accordingly.

public function confirmDeleteBulk()
    {
        $deleteCount = $this->selectedRowsQuery->count();
        foreach ($this->selectedRowsQuery->get() as $queryRow) {
            $queryRow->roles()->detach();
        }
        $this->selectedRowsQuery->delete();
        $this->showUserBulkDeletionModal = false;
        $this->notify('You\'ve deleted '.$deleteCount.' users');
    }

I tried making a separate livewire component with public function method to delete the selected data by displaying a confirmation modal but I was unable to pass the selected number of rows to the UserBulkDeletion nested component located at, Livewire/UserManagement/LogicalComponent/UserBulkDeletion. Please tell me the best use case in this situation, incase if what I want is possible. Help will be really appreciated, as I'm trying to do this since 2 weeks now.

Context

  • Livewire version: 2.3.8
  • Laravel version: 8.24.0
  • Alpine version: 2.8.0
  • Browser: Chrome
Jan
19
3 months ago
Activity icon

Started a new Conversation Detach Role From The User And Delete The User In Bulk Along With Livewire Traits

Description

I have a "belongsToMany" eloquent relationship between users and roles . I am creating a CRUD system with capability to do bulk actions. I followed the Livewire Screencasts Bulk Export/Delete and Refactoring For Re-Usability. I have created a trait for the bulk actions, so I'm able to use it out of the box.

I need to detach the role from the user and then delete the user in bulk. I am unable to call roles relationship on a public method property and detach the same. This is how I detach the role for a single user $this->user->roles()->detach(); but I'm unable to do it with $this->selectedRowsQuery->roles()->detach(); in case of bulk user deletion.

Stripped-down, copy-pastable code snippets

  • Livewire/Backend/UserController
public $showUserBulkDeletionModal = false;

public function confirmDeleteBulk()
{
    $deleteCount = $this->selectedRowsQuery->count();
        
    $this->selectedRowsQuery->roles()->detach();
    $this->selectedRowsQuery->delete();
    $this->showUserBulkDeletionModal = false;

    $this->notify('You\'ve deleted '.$deleteCount.' users');
}

public function getRowsQueryProperty()
{
    $query = User::query()
        ->when($this->filters['email'], fn($query, $email) => $query->where('email', 'like', '%'.$email.'%'))
        ->when($this->filters['role'], fn($query, $role) => $query->whereHas('roles', fn ($query) => $query->where('id', $role)))
        ->when($this->filters['search'], fn($query, $search) => $query->where('name', 'like', '%'.$search.'%'))
        ->when($this->filters['date-min'], fn($query, $created_at) => $query->where('created_at', '>=', Carbon::createFromFormat('d/m/Y', $created_at)))
        ->when($this->filters['date-max'], fn($query, $created_at) => $query->where('created_at', '<=', Carbon::createFromFormat('d/m/Y', $created_at)));
        
    return $this->applySorting($query);
}
  • Livewire/Traits/WithBulkActions
trait WithBulkActions
{
    public $selectPage = false;
    public $selectAll = false;
    public $selected = [];

    public function renderingWithBulkActions()
    {
        if ($this->selectAll) $this->selectPageRows();
    }

    public function updatedSelected()
    {
        $this->selectAll = false;
        $this->selectPage = false;
    }

    public function updatedSelectPage($value)
    {
        if ($value) return $this->selectPageRows();

        $this->selectAll = false;
        $this->selected = [];
    }

    public function selectPageRows()
    {
        $this->selected = $this->rows->pluck('id')->map(fn($id) => (string) $id);
    }

    public function selectAll()
    {
        $this->selectAll = true;
    }

    public function getSelectedRowsQueryProperty()
    {
        return (clone $this->rowsQuery)
            ->unless($this->selectAll, fn($query) => $query->whereKey($this->selected));
    }
}

Context

  • Livewire version: 2.3.6
  • Laravel version: 8.23.1
  • Alpine version: 2.8.0
  • Browser: Chrome
Jan
14
4 months ago
Activity icon

Started a new Conversation How Can I Load Custom Scrollbar With Turbolinks?

How to load custom scrollbar, alongside turbolink page reload. The custom scrollbar loads at the first page load, but after re-directing to the navigation links, the scrollbar breaks. Here is the DOM where the scrollbar wrapper is placed.

Here is the library which I am currently using idiotWu/smooth-scrollbar.

  • resource/views/layouts/app.blade.php
<body>
        <div id=“scroll-wrapper>
        
               <!- - Content- ->
                
        </div>
</body>