Razvan Zamfir
Razvan Zamfir

Reputation: 4626

What is the cause of this route-related error in my Laravel 8 application?

I am working on a Laravel application that requires user registration and login.

Alter registration, the users have the possibility to replace the default avatar image with a picture of their choice.

They should also be able to delete this picture and revert to the default avatar (default.png). For this purpose I did the following:

In routes/web.php I have the necessary routes:

Auth::routes();

Route::get('/dashboard', [App\Http\Controllers\Dashboard\DashboardController::class, 'index'])->name('dashboard');

Route::get('/dashboard/profile', [App\Http\Controllers\Dashboard\UserProfileController::class, 'index'])->name('profile');

Route::post('/dashboard/profile/update', [App\Http\Controllers\Dashboard\UserProfileController::class, 'update'])->name('profile.update');

Route::post('/dashboard/profile/deleteavatar', [App\Http\Controllers\Dashboard\UserProfileController::class, 'deleteavatar'])->name('profile.deleteavatar');

In Controllers\Dashboard\UserProfileController.php I have:

// Delete avatar
public function deleteavatar($id) {
    $current_user = Auth::user();

    if ($id == $current_user->avatar) {
        $current_user->avatar = "default.png";
        $current_user->update();
    }
}

In the view I have this delete button:

<a href="#" class="icon text-light" id="delete-avatar" data-uid="{{$current_user->id}}"><i class="fa fa-trash"></i></a>

The method is executed via AJAX:

(function() {
  //Delete Avatar
  $('#delete-avatar').on('click', function(evt){
    evt.preventDefault();
    var $avatar = $('#avatar-container').find('img');
    var $topAvatar = $('#top_avatar');
    var $trashIcon = $('#delete-avatar');
    var defaultAvatar = APP_URL + '/images/avatars/default.png';

    //Get user's ID
    var id = $(this).data('uid');

    if(confirm('Delete the avatar?')) {
      $.ajax({
        url: APP_URL + '/dashboard/profile/deleteavatar/' + id,
        method: 'GET',
        dataType: 'html',
        success: function(){
          $avatar.attr('src', defaultAvatar);
          $topAvatar.attr('src', defaultAvatar);
          $trashIcon.remove();
        }
      });
    }
  });
})();

The problem

For a reason I was unable to figure out, whenever I click the delete button, I get this error in the browser:

http://larablog.com/dashboard/profile/deleteavatar/1 404 (Not Found)

What am I doing wrong?

Upvotes: 0

Views: 475

Answers (3)

Razvan Zamfir
Razvan Zamfir

Reputation: 4626

Here is the final version I got:

In routes\web.php:

Route::post('/dashboard/profile/deleteavatar/{id}', [App\Http\Controllers\Dashboard\UserProfileController::class, 'deleteavatar'])->name('profile.deleteavatar');

In the controller:

// Delete avatar
public function deleteavatar($id) {
    $current_user = Auth::user();
    $current_user->avatar = "default.png";
    $current_user->save();
}

In app.js:

(function() {
    //Delete Avatar
    $('#delete-avatar').on('click', function(evt) {
        evt.preventDefault();
        var $avatar = $('#avatar-container').find('img');
        var $topAvatar = $('#top_avatar');
        var $trashIcon = $(this);
        var defaultAvatar = APP_URL + '/images/avatars/default.png';

        //Get user's ID
        var id = $(this).data('uid');

        if (confirm('Delete the avatar?')) {
            var CSRF_TOKEN = $('meta[name="csrf-token"]').attr('content');
            $.ajax({
                url: APP_URL + '/dashboard/profile/deleteavatar/' + id,
                method: 'POST',
                data: {
                    id: id,
                    _token: CSRF_TOKEN,
                },
                success: function() {
                    $avatar.attr('src', defaultAvatar);
                    $topAvatar.attr('src', defaultAvatar);
                    $trashIcon.remove();
                }
            });
        }
    });
})();

It works.

many thanks to all that helped.

Upvotes: 1

John Lobo
John Lobo

Reputation: 15319

You have define your route as post method

Route::post('/dashboard/profile/deleteavatar', [App\Http\Controllers\Dashboard\UserProfileController::class, 'deleteavatar'])->name('profile.deleteavatar');

In ajax you passing as

     if(confirm('Delete the avatar?')) {
 var CSRF_TOKEN = $('meta[name="csrf-token"]').attr('content');
          $.ajax({
            url: APP_URL + '/dashboard/profile/deleteavatar/' + id,
            method: 'POST',
            data:{
    id:id,
_token: CSRF_TOKEN,
    }
            success: function(){
              $avatar.attr('src', defaultAvatar);
              $topAvatar.attr('src', defaultAvatar);
              $trashIcon.remove();
            }
          });
        }

Updated

As i see your code ,you are trying to delete loggedin user avatar .So

public function deleteavatar() {

        $current_user = Auth::user();

        $current_user->avatar = "default.png";
        $current_user->save();
    
}

Change route as

Route::get('/dashboard/profile/deleteavatar', [App\Http\Controllers\Dashboard\UserProfileController::class, 'deleteavatar'])->name('profile.deleteavatar');

In Ajax

(function() {
  //Delete Avatar
  $('#delete-avatar').on('click', function(evt){
    evt.preventDefault();
    var $avatar = $('#avatar-container').find('img');
    var $topAvatar = $('#top_avatar');
    var $trashIcon = $('#delete-avatar');
    var defaultAvatar = APP_URL + '/images/avatars/default.png';

    //Get user's ID
    var id = $(this).data('uid');

    if(confirm('Delete the avatar?')) {
      $.ajax({
        url: APP_URL + '/dashboard/profile/deleteavatar/',
        method: 'GET',
        dataType: 'html',
        success: function(){
          $avatar.attr('src', defaultAvatar);
          $topAvatar.attr('src', defaultAvatar);
          $trashIcon.remove();
        }
      });
    }
  });
})();

Upvotes: 1

shaedrich
shaedrich

Reputation: 5735

It either has to be:

  1. GET (like ajax)
Route::post('/dashboard/profile/deleteavatar/{id}', [App\Http\Controllers\Dashboard\UserProfileController::class, 'deleteavatar'])->name('profile.deleteavatar');

and

$.ajax({
        url: APP_URL + '/dashboard/profile/deleteavatar/' + id,
        method: 'POST',
        dataType: 'html',
        success: function(){
          $avatar.attr('src', defaultAvatar);
          $topAvatar.attr('src', defaultAvatar);
          $trashIcon.remove();
        }
});
  1. POST (like route)
Route::get('/dashboard/profile/deleteavatar/{id}', [App\Http\Controllers\Dashboard\UserProfileController::class, 'deleteavatar'])->name('profile.deleteavatar');

and

$.ajax({
        url: APP_URL + '/dashboard/profile/deleteavatar/' + id,
        method: 'GET',
        dataType: 'html',
        success: function(){
          $avatar.attr('src', defaultAvatar);
          $topAvatar.attr('src', defaultAvatar);
          $trashIcon.remove();
        }
});
  1. DELETE (RESTful)
Route::delete('/dashboard/profile/deleteavatar/{id}', [App\Http\Controllers\Dashboard\UserProfileController::class, 'deleteavatar'])->name('profile.deleteavatar');

and

$.ajax({
        url: APP_URL + '/dashboard/profile/deleteavatar/' + id,
        method: 'DELETE',
        dataType: 'html',
        success: function(){
          $avatar.attr('src', defaultAvatar);
          $topAvatar.attr('src', defaultAvatar);
          $trashIcon.remove();
        }
});

Upvotes: 1

Related Questions