DEV Community

mohamed benhida
mohamed benhida

Posted on

The Magic Laravel Helper tap()

Hello,

In this post we will talk about how tap() helper works and where can we used in our projects.

First of all, let's talk about what tap() exactly do behind the scenes.

<?php
function tap($value, $callback = null)
    {
        if (is_null($callback)) {
            return new HigherOrderTapProxy($value);
        }

        $callback($value);

        return $value;
    }
Enter fullscreen mode Exit fullscreen mode

After using tap() you must know that the very first thing we pass it is always what is going to be returned to us.

Let's work with an example so we can more see the differences. for now let's say the $callback is not null and our tap() helper is like that.

<?php
function tap($value, $callback)
    {
        $callback($value);

        return $value;
    }
Enter fullscreen mode Exit fullscreen mode

Our example is that we want to update an user and in the same return the edited $user.

<?php
public function update(Request $request,User $user)
{
   $user = $user->update($param);//return boolean
}
Enter fullscreen mode Exit fullscreen mode

We all know that update() returns boolean but we want it to return our edited $user so we can pass it to our json response for example.Here come the rule of tap()

<?php
public function update(Request $request,User $user)
  {
     $user = tap($user,function($user) use($request){
         $user->update($request->all());
        }); //returns Edited User
  }
Enter fullscreen mode Exit fullscreen mode

We passed $user and a closure that accept $user and runs update() method.

the $callback($value); will be triggered and it will returns the $value at the end in our case it returns $user model.

But this is not helpfull it looks disgusting because we need to passe $request to closure and adding extra two lines.

so here comes the rule of a nulled $callback that will return a new HigherOrderTapProxy($value); that helps us solve the problem above.

Let's understand together what HigherOrderTapProxy($value) really does.

<?php

namespace Illuminate\Support;

class HigherOrderTapProxy
{

    public $target;

    public function __construct($target)
    {
        $this->target = $target; //target in our case is $user model
    }

    //when we call a method it will trigger this function
    public function __call($method, $parameters) 
    {
        $this->target->{$method}(...$parameters); //$user->update($parameters)

        return $this->target; //return $user;
    }
}
Enter fullscreen mode Exit fullscreen mode

Like we see HigherOrderTapProxy class accept $value and each time we call a method inside this class it will trigger the __call() function then the method will apply to the $value passed then it will return it.

like you see in the comments above. now if you really understand how HigherOrderTapProxy works you can just do this and it will works.

<?php
public function update(Request $request,User $user)
 {
   $user = tap($user)->update($request->all());//return edited $user
 }
Enter fullscreen mode Exit fullscreen mode

and here we have the same value with a code on one line.

I hope your enjoyed reading this article.

Top comments (0)