Unable to resolve dependency - Laravel

11,132

$customerId should be in the constructor:

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;
use Google\Ads\GoogleAds\Lib\V3\GoogleAdsClientBuilder;

class BudgetFetch implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private $customerId;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($customerId)
    {
        $this->customerId = $customerId;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $customerId = $this->customerId;
        $clientId = "xxxxxxxxxxxx";
        $clientSecret = "xxxxxxxxxxx";
        $refreshToken = "xxxxxxxxxxxxxxxxxx";
        $developerToken = "xxxxxxxxxxxxxxxxxx";
        $loginCustomerId = "xxxxxxxxxxx";

        $oAuth2Credential = (new OAuth2TokenBuilder())
            ->withClientId($clientId)
            ->withClientSecret($clientSecret)
            ->withRefreshToken($refreshToken)
            ->build()
        ;

        $googleAdsClient = (new GoogleAdsClientBuilder())
            ->withDeveloperToken($developerToken)
            ->withLoginCustomerId($loginCustomerId)
            ->withOAuth2Credential($oAuth2Credential)
            ->build()
        ;

        $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
        $query = 'SELECT campaign.id, campaign.name, metrics.cost_micros, campaign_budget.amount_micros FROM campaign ORDER BY campaign.id';
        /** @var GoogleAdsServerStreamDecorator $stream */
        $stream =
            $googleAdsServiceClient->searchStream($customerId, $query);

        foreach ($stream->iterateAllElements() as $googleAdsRow) {
            /** @var GoogleAdsRow $googleAdsRow */
            $metrics = $googleAdsRow->getMetrics();
            $id = $googleAdsRow->getCampaign()->getId()->getValue();
            $name = $googleAdsRow->getCampaign()->getName()->getValue();
            $spend = $googleAdsRow->getCampaignBudget()->getAmountMicros()->getValue();
            $budget = $metrics->getCostMicrosUnwrapped();

            if($spend >= $budget){
                DB::table('budget_alerts')->insert(
                    ['campaign' => $id, 'hitBudget' => 1]
                );
            };
        }
    }
}

The reason is because the job is not invoked immediately. It is first constructed and then put in the queue where it will (at some point) be removed and "handled". Therefore handle does not have direct access to whatever parameter you pass in dispatch. The docs do show that handle can take parameters but those are only parameters that can be injected using dependency injection.

Share:
11,132
byond temp
Author by

byond temp

Updated on June 22, 2022

Comments

  • byond temp
    byond temp almost 2 years

    Illuminate\Contracts\Container\BindingResolutionException Unable to resolve dependency [Parameter #0 [ $customerId ]] in class App\Jobs\BudgetFetch

    namespace App\Http\Controllers;
    use App\Jobs\BudgetFetch;
    use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;
    use Google\Ads\GoogleAds\Lib\V3\GoogleAdsClientBuilder;
    use Illuminate\Support\Facades\DB;
    
    class APIController extends Controller
    {
        public function index() {
            $clients = DB::table('account_names')->pluck('code');
    
            foreach($clients as $customerId) {
                budgetFetch::dispatch($customerId);
            }
        }
    }
    

    The above is a simple controller I've put together to trigger another job which is;

    namespace App\Jobs;
    
    use Illuminate\Bus\Queueable;
    use Illuminate\Contracts\Queue\ShouldQueue;
    use Illuminate\Foundation\Bus\Dispatchable;
    use Illuminate\Queue\InteractsWithQueue;
    use Illuminate\Queue\SerializesModels;
    use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;
    use Google\Ads\GoogleAds\Lib\V3\GoogleAdsClientBuilder;
    
    class BudgetFetch implements ShouldQueue
    {
        use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    
        /**
         * Create a new job instance.
         *
         * @return void
         */
        public function __construct()
        {
    
        }
    
        /**
         * Execute the job.
         *
         * @return void
         */
        public function handle($customerId)
        {
            $clientId = "xxxxxxxxxxxx";
            $clientSecret = "xxxxxxxxxxx";
            $refreshToken = "xxxxxxxxxxxxxxxxxx";
            $developerToken = "xxxxxxxxxxxxxxxxxx";
            $loginCustomerId = "xxxxxxxxxxx";
    
            $oAuth2Credential = (new OAuth2TokenBuilder())
                ->withClientId($clientId)
                ->withClientSecret($clientSecret)
                ->withRefreshToken($refreshToken)
                ->build()
            ;
    
            $googleAdsClient = (new GoogleAdsClientBuilder())
                ->withDeveloperToken($developerToken)
                ->withLoginCustomerId($loginCustomerId)
                ->withOAuth2Credential($oAuth2Credential)
                ->build()
            ;
    
            $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
            $query = 'SELECT campaign.id, campaign.name, metrics.cost_micros, campaign_budget.amount_micros FROM campaign ORDER BY campaign.id';
            /** @var GoogleAdsServerStreamDecorator $stream */
            $stream =
                $googleAdsServiceClient->searchStream($customerId, $query);
    
            foreach ($stream->iterateAllElements() as $googleAdsRow) {
                /** @var GoogleAdsRow $googleAdsRow */
                $metrics = $googleAdsRow->getMetrics();
                $id = $googleAdsRow->getCampaign()->getId()->getValue();
                $name = $googleAdsRow->getCampaign()->getName()->getValue();
                $spend = $googleAdsRow->getCampaignBudget()->getAmountMicros()->getValue();
                $budget = $metrics->getCostMicrosUnwrapped();
    
                if($spend >= $budget){
                    DB::table('budget_alerts')->insert(
                        ['campaign' => $id, 'hitBudget' => 1]
                    );
                };
            }
        }
    }
    

    The error at the top of the question is what I get from this, If I put the variable in __construct the same thing happens. I've run a php artisan clear-compiled which I found in another question similar and it didn't seem to fix anything.

  • CrazyDev
    CrazyDev almost 4 years
    This is correct. Yes. @byond temp you should receive parameter via constructor instead of handler method.