Job Batching in Laravel and Vue
Tags: vue, laravel, javascript, tutorial
Published: 2023-02-09 09:30:36

Laravel queue enables us to run processes in the background and avoid us having to wait for a response. This functionality enables us to be able to run heavy processes with slowing down browser/ user experience. However, what if the user would like to get real-time update on the processes going on in the background? The best way is to present live information or a progress bar. From Laravel 8, we have **Job Batching**.
According to Laravel doc, Laravel's job batching feature allows you to easily execute a batch of jobs and then perform some action when the batch of jobs has completed executing.

To get started, we would need a database migration to create our table to contain information about job batching:

```
php artisan queue:batches-table
php artisan migrate
```

## In the MailController,

```
use Illuminate\Bus\Batch;
use Illuminate\Support\Facades\Bus; 
use App\Models\User;
public function runJob(Request $request)
    {
	 $users= User::get();
        //create a batch queue 
        $batch = Bus::batch([
		//All jobs here
            new SendEmail($users),
        ])->then(function (Batch $batch) {
            // All jobs completed successfully...
            logger('Batch ' . $batch->id . ' finished successfully!');            
        })->catch(function (Batch $batch, Throwable $e) {
            // First batch job failure detected...
            logger('Batch ' . $batch->id . ' did not finish successfully!');
        })->finally(function (Batch $batch) {
            // The batch has finished executing...
            logger('Cleaning leftovers from batch ' . $batch->id);
        }) ->name('send_email)->dispatch();
         
        return $batch->id;            
    }
public function checkBatchProgress()
{
    $batches = DB::table('job_batches')->where([['pending_jobs','>',0],['name','=','send_email’]])->orderBy('created_at', 'desc')->limit(10)->get();
    if(count($batches) > 0){
        $job_status = Bus::findBatch($batches[0]->id)->toArray();
        $response = round($job_status['progress'],0);
	return $response;
    }else{
        $response = 0;
	return $response;
    }
}
 
```
## Create a job called SendEmail using the artisan command:

```
php artisan make:job SendEmail
```

### Add batchable to jobs

```
use Illuminate\Bus\Batchable;

class SendEmail implements ShouldQueue
{
    use Batchable,  Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    ...
}
```

## To create a progress bar, we need to add code to SendEmail.vue:

```
<template>
<div>
<div class="progress">
  <div class="progress-bar" role="progressbar" :aria-valuenow="timer"
  aria-valuemin="0" aria-valuemax="100" :style={width:timer +’%’}">{{
    <span class="sr-only">{{timer}}% Complete</span>
  </div>
</div>
</div>

</template>
<script>
data() {
  return {
    timer: 0
  }
},
mounted: function () {
	//run the function every 1 second
  this.timer = setInterval(() => {
    this.batchProgress()
  }, 1000)
},
beforeDestroy() {
  clearInterval(this.timer)
},
methods: {
      batchProgress(){
        //make a fetch or axios request to the endpoint 
        axios.get('/api/batchupdate').then(response=>{
          this.timer = response.data;
            })

      },
</script>
```

## In the routes/api.php create a new route

```
Route::get(batchupdate, 'MailController@checkBatchProgress');
```

Finally, don't forget to instruct your application to use the database driver by updating the QUEUE_CONNECTION variable in your application's .env file:

```
QUEUE_CONNECTION=database
```