This takes the references to the original controller function, overrides it with our own version and inside it calls the original controller function using apply on the special âthisâ variable. Whenever AngularJS wants to instantiate a controller for this directive, it will first call our function, after which I call the original function.Â
By passing âthisâ as the first argument, I am effectively extending the current object with whatever the original controller code is doing. The âargumentsâ simply pass all incoming arguments as an array to the original controller code.Â
Keep in mind this has to match the original controller code exactly! If you intend on injecting additional AngularJS services for use in your own logic later on, itâs better to use call() instead and pass all required arguments manually.
If you were to do a console.log(this) after calling the apply(), it would look exactly like the original and also contains the addTag function I want to override.
Â
Hooking the function
Itâs time to add my own logic! Just like C#, JavaScript has the concept of public- and private-modifiers when extending classes, even though it is not as apparent.
When I extend the original controller, I only get public access to the properties the original code explicitly added to âthisâ-variable (or by proxy using the vm-variable). Because the original code does âvm.addTag = addTagâ, âthisâ now contains a public property which is a reference to the private function addTag. Anything not added to âthisâ is private and can never be accessed, no matter how hard you try.
Luckily, the vm.addTag is exactly what I need, so letâs hook that too using the same trick as we did with the controller:
- Store the original reference in a variable
- Replace the property with a new implementation
- Call the original function when needed
This trick is similar to one in the Reverse Engineering world called a âtrampoline hook.â You redirect a function call to another function and then back to the original. In a Reverse Engineering situation you would, however, replace the actual function in memory, whereas I am âjustâ replacing a property referencing the actual function. This is going to pose a problem later on, but Iâll get back to that!
Below the apply-call in your code, paste the following: