2

I've been trying on this tutorial (https://www.youtube.com/watch?time_continue=7&v=D4ny-CboZC0) with respect to my context and I'm getting this error:

POST http://127.0.0.1:8000/transactions/fetch 500 (Internal Server Error)

enter image description here

create.blade.php

@extends('layouts.app')
@section('title', 'New Transaction')
@section('content')
<form action="/transactions" method="POST">
    <div class="row">
        <label>Item Name</label>
        <input type="text" name="item_name" id="item_name" class="form-control input-lg" placeholder="Item Name">
        <div id="itemList"></div>
        {{ csrf_field()}}
        <label>Quantity</label>
        <input type="text" name="quantity[]"  value="" placeholder="Quantity">
        {{ $errors->first('quantity')}}
    </div>
    <button type="submit" class="btn btn-primary">Complete Order</button>
    @csrf
</form>

<script type="text/javascript">
$(document).ready(function(){
    $('#item_name').keyup(function(){
        var query = $(this).val();
        if(query!=''){
            var _token = $('input[name="_token"]').val();
            console.log(_token);
            $.ajax({
                url: "{{route('autocomplete.fetch')}}",
                method: "POST",
                data: {query: query, _token:_token},
                success:function(data){
                    $('#itemList').fadeIn();
                    $('#itemList').html(data);
                }
            })
        }
    });
})
</script>
@endsection

fetch function in TransactionController.php

public function fetch(Request $request)
{
    if($request->get('query')) {
        $query= $request->get('query');
        $data = DB::table('items')
        ->where('item_name', 'LIKE', '%{$query}%')
        ->get();
    }

    $output = '<ul class="dropdown-menu" style="display:block; position:relative">';
    foreach ($data as $row) {
        $output.= '<li> <a href="#">' .$row->item_name.'</a></li>';
    }
    $output .= '</ul>';
    echo $output;
}

web.php

Route::resource('transactions', 'TransactionController');
Route::post('/transactions/fetch', 'TransactionController@fetch')->name('autocomplete.fetch');

Kindly help me find out where exactly the problem is. I tried many methods seen online but none worked.

Thanks in advance!

IGP
  • 14,160
  • 4
  • 26
  • 43
FEBzX
  • 367
  • 2
  • 5
  • 15
  • What is the error in the logs? You can find it in `storage/logs` – Chin Leung Oct 08 '19 at 18:06
  • Please go to your network. You will find error details there. – Rashed Hasan Oct 08 '19 at 18:09
  • If you are getting a 500 error, there is a good chance that your Laravel `storage/logs` are not getting the error. Please also check the web servers error log. – Alex Barker Oct 08 '19 at 18:25
  • @ChinLeung Thanks for the help. I could go through & fix it. But now I can see that the $data variable is empty. The query is not fetching any values. I've cross-checked the table name & column names. Any idea why it's not getting any data? – FEBzX Oct 08 '19 at 18:26
  • I think you need to change the quotes `'%{$query}%'` to `"%{$query}%"` because the single quotes doesn't allow you to use a variable in it https://stackoverflow.com/a/3446286/8068675 – Clément Baconnier Oct 08 '19 at 18:36

2 Answers2

6

Would you please use ->where('item_name', 'LIKE', '%' . $query . '%') instead of ->where('item_name', 'LIKE', '%{$query}%').

if($request->get('query')){
      $query= $request->get('query');
      $data = DB::table('items')
              ->where('item_name', 'LIKE', '%' . $query . '%')
              ->get();
}

It's working for me.

Rashed Hasan
  • 3,721
  • 11
  • 40
  • 82
0

You're very close to get the solution. But I thin your error comes from here: $data variable in your controller will be an array, so in your foreach body you got an error from here

$row->item_name

So instead of this:

$data = DB::table('items')
       ->where('item_name', 'LIKE', '%{$query}%')
       ->get();

Write this (assume that your model name is "Item"):

$data = Item::where('item_name', 'LIKE', '%{$query}%')->get();

IMHO this will solve the problem. But this will return only case sensitive values. For example if you will type "abc", it will not return the words with "ABC". So for that you can just make 2 sides as uppercase and compare. Like this:

$data = Item::whereRaw("UPPER(item_name) LIKE '%" . strtoupper($query) . "%'")->get();

If you want to go forward and search also the special characters, then I think this answer will be not only the answer of your question. But at the this moment I recommend you to use the last row.

boolfalse
  • 1,892
  • 2
  • 13
  • 14
  • It worked. But can you explain why it's not working with normal where? – FEBzX Oct 08 '19 at 18:35
  • About the case sensitive, it depends of the collation. `utf8_general_ci` will be Case Insensitive while `utf8_general_cs` will be Case Senstive – Clément Baconnier Oct 08 '19 at 18:40
  • $items = DB::table('items')->where(...)->get() will return an array. But $items = Item::where(...)->get() will return a collection. So that's why you can't access to $data->something when you're using DB Query – boolfalse Oct 08 '19 at 18:42
  • 2
    Do **not** use the final example as is. Never pass unescaped/unsanitized data directly into raw SQL. https://www.owasp.org/index.php/SQL_Injection – deefour Oct 08 '19 at 19:00
  • @deefour doesn't Model approach supports PDO ?? As far as I know we shouldn't use DB query, but we can use model approach, or in the bad case we can use binding.. isn't ? – boolfalse Oct 08 '19 at 19:03
  • Straight from [the docs](https://laravel.com/docs/6.x/queries#raw-expressions): __Raw statements will be injected into the query as strings, so you should be extremely careful to not create SQL injection vulnerabilities.__ – deefour Oct 08 '19 at 19:46
  • Yes you're right. thanks for the info. May readers in further will be acknowledged, but also good to know that this $users = User::whereRaw("UPPER(name) LIKE '%" . strtoupper($name) . "%'"); will return Query Builder, from which you can call ->get() I just didn't found that in the docs (may it not there). But we can check that here in [this example](https://stackoverflow.com/questions/20864872/how-to-bind-parameters-to-a-raw-db-query-in-laravel-thats-used-on-a-model#answer-20873009) About PDO security we can see [here](https://laravel.com/docs/6.x/queries#introduction), which we have – boolfalse Oct 08 '19 at 20:11
  • So that's normal to use model approach (NOT DB::where(...)), that's secure. But about docs I'm confused... why it in't in the off docs.. – boolfalse Oct 08 '19 at 20:15
  • Only the `raw` queries are insecure and it's well written in the doc. `DB::where() ` is secure – Clément Baconnier Oct 09 '19 at 05:43
  • I downvoted you because almost nothing is right in your answer. The only thing that will work and that you recommand is a security issue. Please fix it. The only (?) issue in the question are the quotes. – Clément Baconnier Oct 09 '19 at 05:57