phplaravellaravel-5laravel-response

Error on adding macro for response helper chained with json method in Laravel 5


I'm working on a Laravel 5 Application that only uses API routes. I created a macro to extend the add cookie method of the response helper. But I encountered an error that my macro doesn't exist.

We are using this for returning response:

return response()->json($data, $status)
  ->cookie(
     'COOKIE_NAME',
     $value,
     $expiration,
     '/',
     app()->environment('production') ? config('app.domain') : null,
     app()->environment('production'),
     true
  );

as the data beyond the expiration is always the same for all endpoint with cookie, I want to create a macro that will automatically adds that data to the cookie and reduce the code to this:

return response()->json($data, $status)
  ->httpCookie('COOKIE_NAME, $value, $expiration);

I have created a ResponseServiceProvider and add the macro using Response::macro method.

Here is my macro code:

public function boot()
{
  Response::macro('httpCookie', function ($name, $value, $expiration) {
    $isProd = app()->environment('production');
    return response()->cookie(
      $name, 
      $value,
      $expiration,
      '/',
      $isProd ? config('app.domain') : null,
      $isProd,
      true
    );
  });
}

Then trying to test the endpoint, I ran to an error:

BadMethodCallException
Method Illuminate\Http\JsonResponse::httpCookie does not exist.

How can I solve this problem? Thanks.


Solution

  • When I look at the Illuminate\Support\Facades\Response class, the Response Facade proxies the Illuminate\Routing\ResponseFactory class. Though the ResponseFactory is also macroable, it is used for a different purpose.

    So please add a macro to the correct class, in this case I think Illuminate\Http\Response:

    use Illuminate\Http\Response;
    
    public function boot()
    {
      Response::macro('httpCookie', function ($name, $value, $expiration) {
        $isProd = app()->environment('production');
        return $this->cookie(
          $name, 
          $value,
          $expiration,
          '/',
          $isProd ? config('app.domain') : null,
          $isProd,
          true
        );
      });
    }