Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

siggi's avatar
Level 5

get job Id from dispatch in controller

Hello everyone,

we currently use laravel 8, and generate a "lock file" that generates an empty file so a "generating..." tile can be displayed in another app.

As the job might take some time to be handled, we dispatched from the controller and generated a lock file there like

$jobId = $this->dispatch(new ReportExportNew(auth()->user()->id, $serializedQuery, $isAdmin));
$this->generateLockFile($jobId);

unfortunately, after upgrading to laravel 10, this no longer seems to work as dispatch does no longer return anything at all.

Does anyone have a solution for this?

1 like
11 replies
tisuchi's avatar

@siggi This might help you:

In your ReportExportNew class:


class ReportExportNew
{
    use InteractsWithQueue;

    public $jobId;

    // Other properties/methods...

    public function queue($queue, $command)
    {
        $this->jobId = $this->job->getJobId();
        $queue->push($command);
    }
}

Now call this way:


$job = new ReportExportNew(auth()->user()->id, $serializedQuery, $isAdmin);
dispatch($job);
$jobId = $job->jobId;
$this->generateLockFile($jobId);
friedaritter's avatar

If the dispatch method in Laravel 10 no longer returns the job instance, you can try using the dispatchNow method, which executes the job immediately and returns the job instance. Here's an example: $job = new ReportExportNew(auth()->user()->id, $serializedQuery, $isAdmin); $jobId = dispatchNow($job); $this->generateLockFile($jobId);

siggi's avatar
Level 5

@tisuchi thanks for your reply.

Unfortunately, this does not seem to work, as $this->job is apparently null in the queue function:

Call to a member function getJobId() on null

@friedaritter

dispatchNow does not seem to be a function, and the dispatch_now helper function is marked as deprecated in 8, and also does not seem to work. So I guess this method does not exist any more in Laravel 10 :/

siggi's avatar
Level 5

@tisuchi unfortunately yes:

public function queue($queue, $command)
    {
        $this->jobId = $this->job->getJobId();
        $queue->push($command);
    }

and in controller

$job = new ReportExportNew(auth()->user()->id, $serializedQuery, $isAdmin);
            dispatch($job);
            dd($job);

leads to

Call to a member function getJobId() on null

I tested to generate a random string as jobId in the queue method, which seems to work. But this is not the way I really want to go

kevinbui's avatar

I have just checked the source code. And yes, according to @tisuchi, the key to solve your problem is the getJobId method. And I think we can simply do this:

$jobId = ReportExportNew::dispatch(auth()->user()->id, $serializedQuery, $isAdmin)
	->getJobId();
$this->generateLockFile($jobId);

Edited:

Nope, it's not that easy :). The job is really dispatched within the destructor of the Illuminate\Foundation\Bus\Dispatcher class. So I believe we don't get the job id till the program exits.

I am thinking about registering a listener for the Illuminate\Queue\Events\JobQueued event:

use Illuminate\Queue\Events\JobQueued;

class GenerateLockFile
{
    public function handle(JobQueued $event): void
    {
        if (...) {
            // The $id property of the $event object is the id of the queued job.
            $this->generateLockFile($event->id);
        }
    }
}
martinbean's avatar

@siggi You should instead create your own model to hold the status of whatever this process is.

Create a model instance with a default status of pending when dispatching the job. Then update the status to processing when handling the job, and to a terminal state such as complete or failed when the job is handled or fails.

AttD7's avatar

Hello @siggi , have a solution :

Step 1: Create a new helper : custom dispatch

function custom_dispatch($job): int {
        return app(\Illuminate\Contracts\Bus\Dispatcher::class)->dispatch($job);
}

Step 2: use our custom dispatch to dispatch our jobs

$job = new App\Jobs\YourAwesomeJob($params);

// Dispath your job with our custom_dispatch helper. This will return job id from jobs table
$jobId = custom_dispatch($job);

return $jobId; // 27 // app\Jobs\YourAwesomeJob.php:52

src :dev.to/mitulmlakhani/laravel-delay-dispatch-queue-job-and-get-job-id-36ke

vagkaefer's avatar

Hi, if you check the docs from laravel v5 you will find some "internal" functions...

\Queue::push(new App\Jobs\YourJob());
\Queue::pushOn('queue-name',new App\Jobs\YourJob());

You can check a lot of functions in Illuminate\Support\Facades\Queue, like later, laterOn, etc.

This functions will return the jobid of your request, this is a way we use in here to solve this problem to have the id of a job in the dispatch process.

$ php artisan tinker
> \Queue::push(new App\Jobs\GenerateQueuesConfig());
= "55fae0ee-7ec0-4f09-9117-7555da36d290" #we use uuid in here, problably you will receive a integer here

Expect that this can help :D

flow96's avatar

For anyone having the same problem and coming here to find a solution - you can use one of the following methods instead to dispatch a job and get the jobId instantly:

$job = new YourJob();
$jobId = Bus::dispatch($job);
// Or
$jobId = Queue::push($job);

It's stated in the Laravel documentation for Tinker in the "usage" section (there is an info box - seems like I am not allowed to post links in here)

2 likes
xmsi's avatar

Thanks it works in Laravel 12

Please or to participate in this conversation.