How to Send an Ajax POST Request to a Laravel Route

AJAX is a widely used technique that allows you to send and receive data in your application and refresh a part of your page, without the need for a full page refresh.

In Laravel, sending data via an AJAX POST request involves adding JavaScript code to your blade view, and processing the received data by implementing a function in the controller. Additionally, you’ll need to define a route linking the controller function to a specific URL.

In this tutorial, we’ll create an example application that can add tasks to a list without a full page refresh. I’ll guide you through each step of the process, including installing Laravel, setting up models, migrations, controllers, routes, and views. I will provide two approaches to send the POST request from your view, one will use Axios and one will use jQuery. You can choose which of them best suits your project requirements

Let’s get started!

Step 1: Install Laravel

If you haven’t already, set up a new Laravel project by running:

composer create-project laravel/laravel laravel-ajax-post

Step 2: Add Database Credentials to .env (Optional)

If you’ve installed Laravel 11 or newer you can use the default Sqlite database connection out of the box without editing any configuration for it. In this case you can skip this step.

Should you wish to use a different database, like MySQL or PostgreSQL, you should edit the file .env accordingly. For example, to use MySQL, you should edit it to look like this:

.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laracoding
DB_USERNAME=my-mysql-username
DB_PASSWORD=my-mysql-password

This assumes you’ve installed a MySQL server and created the user named “my-mysql-username” and the database named “laracoding“. Make sure you edit these to match your own database and user names.

Step 3: Create Model to save a Task

Generate a new model named Task using Artisan, along with its migration file:

php artisan make:model Task -m

Step 4: Add Model code

Open the generated Model in app/Models/Task.php and add the following code to make the columns mass assignable:

app/Models/Task.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Task extends Model
{
    protected $fillable = [
        'name',
        'description',
        'completed',
        'due_date'
    ];
}

Step 5: Add Migration Code

Open the migration file created in the database/migrations directory and define the schema for the tasks table using the code below.

For the sake of example, I suggest adding some columns a task would need, such as name, description, status, and due_date:

database/migrations/2024_04_03_204005_create_tasks_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->text('description')->nullable();
            $table->boolean('completed')->default(false);
            $table->dateTime('due_date')->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('tasks');
    }
};

Step 6: Create Controller

Create a new controller named TaskController by runnin the following Artisan command:

php artisan make:controller TaskController

Step 7: Add Controller Code

In the TaskController, implement the index method to load a view and the store method to handle the AJAX POST request:

app/Http/Controllers/TaskController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Task;

class TaskController extends Controller
{
    // Shows all tasks
    public function index()
    {
        return view('tasks.index', ['tasks' => Task::all()]);
    }

    // Handles Ajax POST to create a task
    public function store(Request $request)
    {
        $task = new Task();
        $task->name = $request->input('name');
        $task->save();

        return response()->json($task);
    }
}

Step 8: Create Routes

Using the code below you’ll define a get route to show the index page and a post route to receive post requests for adding new tasks:

routes/web.php
<?php

use App\Http\Controllers\TaskController;
use Illuminate\Support\Facades\Route;

// Shows all tasks
Route::get('/', [TaskController::class, 'index'])->name('tasks.index');

// Handles Ajax POST to create a task
Route::post('/', [TaskController::class, 'store'])->name('tasks.store');

Step 9: Send POST Request Using Axios

Create a view blade file named index.blade.php in the resources/views/tasks directory. This file will contain the HTML for the index page and the form for adding tasks.

You may use the example code below to use Axios for sending the Ajax POST requests:

resources/views/tasks/index.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tasks</title>
    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-sm-6 col-sm-offset-6 p-5">
            <h1 class="mb-4">Tasks</h1>
            <form id="taskForm" class="mb-4">
                <div class="input-group">
                    <input type="text" class="form-control" name="name" placeholder="Enter task name">
                    <button type="submit" class="btn btn-primary">Add Task</button>
                </div>
            </form>
            <ul id="taskList" class="list-group">
                @forelse ($tasks as $task)
                    <li>{{ $task->name }}</li>
                @empty
                @endforelse
            </ul>
        </div>
    </div>
</div>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
    const form = document.getElementById('taskForm');
    form.addEventListener('submit', async (event) => {
        // Make sure the submit button doesn't use a regular / non-ajax submit
        event.preventDefault();

        const formData = new FormData(form);

        try {
            // Send AJAX POST request using Axios
            const response = await axios.post('{{ route('tasks.store') }}', formData);
            const task = response.data;

            const taskList = document.getElementById('taskList');
            const listItem = document.createElement('li');
            listItem.textContent = task.name;
            taskList.appendChild(listItem);

            form.reset();
        } catch (error) {
            console.error('Error:', error);
        }
    });
</script>
</body>
</html>

Should you prefer using jQuery, refer to the code used in the next step instead.

Step 10: Send POST Request Using jQuery (Optional)

In case you wish to use jQuery you can use similar code but replace the script portion of the page as follows:

resources/views/tasks/index.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tasks</title>
    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-sm-6 col-sm-offset-6 p-5">
            <h1 class="mb-4">Tasks</h1>
            <form id="taskForm" class="mb-4">
                <div class="input-group">
                    <input type="text" class="form-control" name="name" placeholder="Enter task name">
                    <button type="submit" class="btn btn-primary">Add Task</button>
                </div>
            </form>
            <ul id="taskList" class="list-group">
                @forelse ($tasks as $task)
                    <li>{{ $task->name }}</li>
                @empty
                @endforelse
            </ul>
        </div>
    </div>
</div>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });
    $(document).ready(function() {
        $('#taskForm').submit(function(event) {
            // Makes sure the submit button doesn't use a regular / non-ajax submit
            event.preventDefault();
            const formData = $(this).serialize();

            // Send AJAX POST request using jQuery
            $.post('{{ route('tasks.store') }}', formData)
                .done(function(response) {
                    // Update task list in the html page
                    const taskList = $('#taskList');
                    const listItem = $('<li>').text(response.name);
                    taskList.append(listItem);

                    // Clear the form
                    $('#taskForm')[0].reset();
                })
                .fail(function(error) {
                    console.error('Error:', error);
                });
        });
    });
</script>
</body>
</html>

Step 11: Run the Application

Now let’s start the Laravel development server by running:

php artisan serve

Afterwards you can open your browser and navigate to http://localhost:8000 to view our index page.

On this page you can use the form to input a name and submit it to create a new task. This form will be sent by a POST request to our TaskController’s store method. When the task was successfully stored it is dynamically added to the unordered list on the index page without the need to refresh the page:

Our Test Application Showing the From to Add a Task and the List of Added Tasks

Congratulations! You’ve successfully implemented sending and processing AJAX POST requests in a Laravel application

Conclusion

In this tutorial you learned to build a controller to receive an AJAX POST request, and a view to send the request using JavaScript. For actually sending the request I’ve covered using either Axios or jQuery.

The example application uses an index page to show a view with a list of tasks and a form to add new tasks. When the form is submitted, new tasks are dynamically added to the list without the need for page reload.

Should you have any questions let me know in the comments below and I’ll try to answer them. Feel free to apply the techniques shown in this tutorial to enhance the interactivity of your own Laravel applications.

Happy Coding!

References

Johan van den Broek

Johan is the creator of laracoding.com. As a child, he began tinkering with various programming languages, many of which have been long forgotten today. Currently, he works exclusively with PHP and Laravel, and his passion for programming remains to this day.

Leave a Reply

Your email address will not be published. Required fields are marked *

Recent Posts