skip to Main Content

I’m currently stuck on an issue where I’m unable to handle 404 or 500 error with jQuery AJAX. I’m fetching some data from controller, and I’m returning json() with relevant status code:

public function getFilteredProducts(Request $request){
    $products = Product::where('product_category_id', $request->category_id)->get();
    if(count($products)){
        return response()->json([
            'products' => $products,
            'category_id' => $request->category_id,
        ], 200);
    }else{
        return response()->json([
            'product_category_id' => $request->category_id
        ], 404);
    }
}

This is my AJAX function:

$.ajax({
            url: `/shop/filtered-products/${category_id}`,
            type: 'get',
            headers: {
                'X-CSRF-TOKEN': window.csrfToken
            },
            success: function (data) {
                //Do something on succes
            },
            statusCode: {
                404: function (data) {
                    //Hande 404 code
                },
                500: function (data) {
                    //Handle 505 code
                }
            }
});

This works perfectly when there are products found & when I return 200 status. But the problem occurs when I return 404 status code & statusCode functions are not getting called. I can see the error in console, but the code is not executing:

enter image description here

I also tried to handle errors with error function, but no luck either:

$.ajax({
            url: `/shop/filtered-products/${category_id}`,
            type: 'get',
            headers: {
                'X-CSRF-TOKEN': window.csrfToken
            },
            success: function (data) {
                //Do something on succes
            },
            error: function (data) {
               //Handle any errors
            },
});

Expected result would be to execute some code on any of the following status codes(404 or 500). What am I doing wrong here? Thanks in advance.

3

Answers


  1. Chosen as BEST ANSWER

    I managed to resolve this by using different parameters in AJAX error function, something like this:

            statusCode: {
                404: function(XMLHttpRequest, textStatus, errorThrown){
                    //Handle 404 error
                },
                500: function(XMLHttpRequest, textStatus, errorThrown){
                    //Handle 500 error
                }
            }
    

    When I added LHttpRequest, textStatus, errorThrown parameters, my error was getting caught in AJAX as expected. To return errors, I used this in controllers to return exceptions:

    return response()->json([
                    'error' => 'Kategorija nema proizvoda',
                    'product_category_id' => $request->category_id
                ], 404);
    

  2. In your controller just thrown an exception, which you can handle in the render function.

    // IN YOUR CONTROLLER, CHANGE THE "else" STATEMENT LIKE THIS
    if(count($products)) {
        return response()->json([
            'products' => $products,
            'category_id' => $request->get('category_id'),
        ], 200);
    } else {
        throw new ModelNotFoundException($request->get('category_id'));
    }
    

    Don’t forget to use this class above:

    // DON'T FORGET TO USE THIS
    use IlluminateDatabaseEloquentModelNotFoundException;
    

    In "app/Exceptions/Handler.php" add the code-block before existing line (by default).

    public function render($request, Throwable $exception)
    {
        // ADD THIS BLOCK IN "app/Exceptions/Handler"
        $product_id = (int)($exception->getMessage());
        if ($exception instanceof ModelNotFoundException) {
            return response()->json([
                'product_category_id' => $product_id,
            ], 404);
        }
    
        return parent::render($request, $exception);
    }
    

    That’s it. But remember, this is just one of many solutions. Actually you can create your custom exceptions and thrown them. For more you can see here

    Login or Signup to reply.
  3. Try to add this:

    $.ajax({     
      headers: {
        //...        
        Accept: "application/json",         
      },
      //...
    });
    

    Handled for you by Laravel expectsJson() in render() method

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search