0

My scenario I have a laravel9 site which is using datatables.net (v1.11.5) and all is good when I use php artisan serve. I'm now working on getting it to serve with a url (http://laravel.ecl using hosts and apache) The url works I can log in my site but when i wish to show my users table that uses the datatables.net script i get an error when trying to build the query.

I notice while looking at the line in question that when using artisan serve it isarray(0 => array(0, "asc")) but when i use the url i get array(0 => 0, 1 => "asc") consequently my code errors Trying to access array offset on value of type int.

This is the relevent part of my blade file:

    <div class="col-xs-12 col-sm-8 col-md-12 clearfix">
        <table id="users" class="eclipse table table-striped table-bordered table-hover">
            <thead>
                <td style="width:34px;">ID</td>
                <td style="width:16px;"> </td>
                <td style="width:220px;">Email</td>
                <td>Name</td>
                <td>Team</td>
                <td>Position</td>
                <td>Role</td>
                <td style="width:88px;">Last Edit</td>
                <td style="width:16px;">Actions</td>
            </thead>
            <tbody>

            </tbody>
        </table>
    </div>

    <script>
        var loader = document.getElementById("loader");
        var menu   = document.getElementById("menu-holder");
        var span   = document.getElementsByClassName("close")[0];
        var modal  = document.getElementById("myModal");
        $(document).ready(function() {
            var table = $('#users').DataTable({
                "serverSide": true,
                "ajax": {
                    url: "/users/data/",
                    method: "get"
                },
                "columnDefs" : [
                    {
                        "targets": [-1],
                        "data": null,
                        "visible": true,
                        "defaultContent": '<button><i class="fas fa-bars"></i></button>'
                    },
                    {
                        "targets": [0],
                        "visible": false
                    }
                ],
            });
            $("#users tbody").on("click", "button", function () {
                var data = table.row( $(this).parents('tr') ).data();
                // Show popup form
                var url = $( this ).data("url");
                // now call ajax on this url
                call_ajax( "/user/" + data[0] + "/action" );
                modal.style.backgroundColor = null;
                modal.style.display = "block";
                menu.style.display = "block";
            });
            $("#add-new-user").on("click", function () {
                // Show popup form
                var url = $( this ).data("url");
                // now call ajax on this url
                call_ajax( url );
                modal.style.display = "block";
                loader.style.display = "block";
            })
            span.onclick = function() {
                loader.style.display = "none";
                modal.style.display = "none";
                menu.style.display = "none";
                modal.style.backgroundColor = '#fefefe';
            }
            window.onclick = function(event) {
                if (event.target == menu) {
                    loader.style.display = "none";
                    modal.style.display = "none";
                    menu.style.display = "none";
                    modal.style.backgroundColor = '#fefefe';
                }
            }
        });

        function call_ajax( url ) {
            $.get( url )
                .done(
                    function( data ) {
                        $("#content-region").html( data );
                    }
                )
                .fail(
                    function() {
                        $("#content-region").html( "<p>error</p>" );
                    }
                );
        }
    </script>

the function in the controller:

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index( Request $request)
    {
        $search = $request->query('search', array('value' => '', 'regex' => false));
        $draw = $request->query('draw', 0);
        $start = $request->query('start', 0);
        $length = $request->query('length', 25);
        $order = $request->query('order', array(1, 'asc')); // << where the wrong values are rendered

        $filter = $search['value'];

        $sortColumns = array(
            0 => 'id',
            1 => 'profile_photo_path',
            2 => 'email',
            3 => 'name',
            4 => 'work_group',
            5 => 'position',
            6 => 'role',
            7 => 'created_at',
            8 => 'actions'
        );

        $query = User::select('users.*')->where('is_enabled', '=', 1);

        if (!empty($filter)) {
            $query->where('name', 'like', '%'.$filter.'%');
        }

        $recordsTotal = $query->count();

        $sortColumnName = $sortColumns[$order[0]['column']]; // << When the error happens

        $query->orderBy($sortColumnName, $order[0]['dir'])
            ->take($length)
            ->skip($start);

        $json = array(
            'draw' => $draw,
            'recordsTotal' => $recordsTotal,
            'recordsFiltered' => $recordsTotal,
            'data' => [],
        );

        $users = $query->get();

        foreach ($users as $user) {
            $json['data'][] = $user->getUserJson();
        }

        return $json;

    }

As explained earlier using php artisan serve works and this was what I have been using to develop until now. Now however I plan to use a proper url for further testing and have this issue. All pages that do not use the datatables functionality are serving correctly, pages that use datatables.net are returning the incorrect data on $order = $request->query('order', array(1, 'asc'));.

6
  • 1
    For me the default value seems fine, check what is submited to the server. Also, you use $order[0]['dir'] and $sortColumns[$order[0]['column']] but it's not present on your default value, it should be array('column' => 1, 'dir' => 'asc') then Commented May 9, 2022 at 13:54
  • I get the following error in my javascript console Uncaught TypeError: Cannot read properties of undefined (reading 'length'). when i step over the code I notice that what is sent to the server in the get statement isn't right. the code breaks trying to get data from the array so I think this is a bit of a red herring? so maybe assign a default? Commented May 9, 2022 at 13:57
  • The error you copy pasted is a php error, that's why i assumed the error was on php side, i think the js error is because of the php error, you don't get any data back and it's not working, try to fix the default value of order, use string or integer keys as you wish but it needs to be consistent Commented May 9, 2022 at 13:59
  • thanks Lk77, I'll have a look what can be done. I do wonder why this worked using artisan serve and not via a url though. The docs didn't mention of setting defaults either but think can work with it. Commented May 9, 2022 at 14:03
  • well perhaps you never used the default value before, and you were submitting that order field, and for some reason on js side, order is not sent anymore and causes issues on php side, it's just a guess it could be something else Commented May 9, 2022 at 14:04

1 Answer 1

1

Thanks to Lk77 for help on this. Following solved my issue

            if ( !isset( $order[0]['column'] ) ) {
                unset( $order );
                $order = array( 0 => array( 'column' => 0, 'dir' =>"asc" ) );
            }

after this it works and once loaded can filter whichever column is needed

Sign up to request clarification or add additional context in comments.

1 Comment

Turned out this didn't fix my issue. The real issue here was no .htaccess in the public folder. I got a copy of the default and everything worked as expected (I had been editing the .htaccess in docroot)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.