Unable to pass the required parameters into the URL - Laravel Inertia Vue

Viewed 4022

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, as a prop, 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>
1 Answers

I recently made a screencast on building a datatable with InertiaJS and Laravel.
The gist of it is:

import AppLayout from '@/Layouts/AppLayout';
import Pagination from '../Jetstream/Pagination';
import { pickBy, throttle } from 'lodash';

export default {
  components: {
    AppLayout,
    Pagination,
  },
  props: {
    users: Object,
    filters: Object,
  },
  data() {
    return {
      params: {
        search: this.filters.search,
        field: this.filters.field,
        direction: this.filters.direction,
      },
    };
  },
  methods: {
    sort(field) {
      this.params.field = field;
      this.params.direction = this.params.direction === 'asc' ? 'desc' : 'asc';
    },
  },
  watch: {
    params: {
      handler: throttle(function () {
        let params = pickBy(this.params);

        this.$inertia.get(this.route('users'), params, { replace: true, preserveState: true });
      }, 150),
      deep: true,
    },
  },
};

Then in the controller index action:

public function index()
{
    request()->validate([
        'direction' => ['in:asc,desc'],
        'field' => ['in:name,city']
    ]);

    $query = User::query();

    if (request('search')) {
        $query->where('name', 'LIKE', '%'.request('search').'%');
    }

    if (request()->has(['field', 'direction'])) {
        $query->orderBy(request('field'), request('direction'));
    }

    return Inertia::render('Users', [
        'users' => $query->paginate()->withQueryString(),
        'filters' => request()->all(['search', 'field', 'direction'])
    ]);
}

You can watch the screencast here.

Related