<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: yanai</title>
    <description>The latest articles on DEV Community by yanai (@yanai101).</description>
    <link>https://dev.to/yanai101</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F106889%2Ffc027943-af15-43cf-9014-028dc81fd9bd.jpeg</url>
      <title>DEV Community: yanai</title>
      <link>https://dev.to/yanai101</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yanai101"/>
    <language>en</language>
    <item>
      <title>The Power of Proxy Api</title>
      <dc:creator>yanai</dc:creator>
      <pubDate>Mon, 25 May 2020 18:32:43 +0000</pubDate>
      <link>https://dev.to/yanai101/the-power-of-proxy-api-g81</link>
      <guid>https://dev.to/yanai101/the-power-of-proxy-api-g81</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--p3doKdvO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/700/0%2A2tMLE_04-N782iPm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--p3doKdvO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/700/0%2A2tMLE_04-N782iPm.jpg" alt="https://pixabay.com/"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Recently I helped in translating the book “&lt;a href="https://github.com/nzakas/understandinges6"&gt;Understanding ECMAScript 6&lt;/a&gt;" to Hebrew (for now the translation process still at work).&lt;/p&gt;

&lt;p&gt;That triggered an interest in the wonderful world of javascript’s Proxy Api- and in this short article I want to present some of the power of this API and show you some useful parts.&lt;br&gt;&lt;br&gt;
So, what is Proxy After all? And why do we need it?&lt;br&gt;&lt;br&gt;
Good questions let’s try to answer them.&lt;/p&gt;
&lt;h2&gt;
  
  
  Some History
&lt;/h2&gt;

&lt;p&gt;Before ES6, The ES5 gave us the ability to decide if a property of a given object is configurable , enumerable , writable and so on &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty"&gt;see here&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
The ES6 is giving the developer more power to control the object’s behavior and give accesses to JS engine capabilities- through Proxies low-level operations of the JavaScript engine.&lt;br&gt;&lt;br&gt;
For example :using proxy you can extend the object to mimic and act like an array- you can read about it in the section &lt;a href="https://github.com/nzakas/understandinges6/blob/master/manuscript/12-Proxies-and-Reflection.md#the-array-problem"&gt;“The Array Problem"&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let see a basic use of proxy:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let targetObject= {}let proxy = new Proxy(targetObject , {})  
proxy.name = 'my name';console.log(proxy.name) // "my name"  
console.log(targetObject.name) // "my name"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When you create a Proxy object you need to pass two parameters to the proxy constructor. the target Object and a handler.&lt;br&gt;&lt;br&gt;
The handler is an object that defines one or more “traps”. A trap is some endpoint to interact with the low-level-api. For example one could trap an object’s getter method and overide it .&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let targetObject = {  
    massage: "hello world",  
    name: "foo"  
};  

let proxy = new Proxy(targetObject, {  
 /// 'get' trap  
    get(trapTarget, key, value, receiver) {  
        if (key === 'massage'){  
           return "hello proxy";  
        }  
       return Reflect.get(trapTarget, key, value, receiver);  
    }  
});

console.log(targetObject.massage) /// 'hello world'  
console.log(proxy.massage) /// 'hello proxy'
console.log(targetObject.name) /// 'foo'  
console.log(proxy.name) /// 'foo'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This article will present some of the most interesting traps that proxy offers us.&lt;/p&gt;
&lt;h2&gt;
  
  
  Reflection &lt;strong&gt;API&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before moving to the amazing traps… we need to be familiar with  &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect"&gt;reflection API&lt;/a&gt;. Because Proxy has an access to the low level methods in JS.&lt;br&gt;&lt;br&gt;
The reflection API- is a collection of methods that serve the default behavior of the same low level methods- for every trap- we have a reflect method …&lt;br&gt;&lt;br&gt;
This is a quick summary:&lt;/p&gt;

&lt;p&gt;The following is a list of methods provided by the reflection API.&lt;br&gt;&lt;br&gt;
In order to call the default low level object’s mathods one needs to use the reflect API. (as we will see next)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_podXb7d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/922/1%2AtK7LH_sK7Lahcy7VKg2RRA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_podXb7d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/922/1%2AtK7LH_sK7Lahcy7VKg2RRA.png" alt="https://github.com/nzakas/understandinges6/blob/master/manuscript/12-Proxies-and-Reflection.md"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So now we have more basic knowledge to continue- and show you the next cool trap in proxy.&lt;/p&gt;
&lt;h2&gt;
  
  
  Preventing Property Deletion
&lt;/h2&gt;

&lt;p&gt;In an object we have the method  &lt;code&gt;deleteProperty&lt;/code&gt;  so similarly proxy has the  &lt;strong&gt;deleteProperty trap&lt;/strong&gt;- it is useful for a lot of things- the basic one is to prevent deletion of property:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let  targetObject  =  {  
   name: "target",  
   lock: "delete not allowed"  
};

let proxy = new Proxy(targetObject,  {  
    deleteProperty(trapTarget, key){  
       if(key === 'lock'){  
          throw new Error('this props are lock')  
       }else{  
        return Reflect.deleteProperty(trapTarget, key)        
      }  
     }  
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The reflect method - it for execute the default behavior…let see it in action:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3UZ-K3U4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/581/1%2A-5_ENJSJZORxd7a9lXXQuA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3UZ-K3U4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/581/1%2A-5_ENJSJZORxd7a9lXXQuA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/vQqeT3AYg8S5O/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/vQqeT3AYg8S5O/giphy.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Blocking defineProperty
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;definePropery&lt;/code&gt; method get three values as arguments: &lt;code&gt;Object.defineProperty(obj,prop,descriptor)&lt;/code&gt; as you can see &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#Syntax"&gt;here&lt;/a&gt; , let see the trap example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let targetObject = {  
   name: "target",  
};  
let proxy = new Proxy(targetObject, {  
    defineProperty(trapTarget, key, descriptor){  
       if(key === 'lock'){  
          throw new Error('this props cannot be defined')  
       }  
        return Reflect.defineProperty(trapTarget, key, descriptor)        
     }  
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And in action :&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sJ15OxxH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/743/1%2AwCN9HeUKk6XoReKVGJCDJg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sJ15OxxH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/743/1%2AwCN9HeUKk6XoReKVGJCDJg.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
Using this trap you can also to make sure that the object structure is what we expect.&lt;/p&gt;
&lt;h2&gt;
  
  
  Hide Property with has trap
&lt;/h2&gt;

&lt;p&gt;You can check if Property exists on object with the  &lt;code&gt;in&lt;/code&gt;  operator, like that:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const targetObject = {foo: 'bar'}  
console.log("foo" in targetObject ) // true
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With the  &lt;code&gt;has&lt;/code&gt;  trap you can hide this Property:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jAyv520Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/497/1%2AGIKkpwLeZh8XFaOSJ1sL2Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jAyv520Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/497/1%2AGIKkpwLeZh8XFaOSJ1sL2Q.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Function proxy- apply and construct
&lt;/h2&gt;

&lt;p&gt;Of all the proxy traps- the  &lt;code&gt;apply&lt;/code&gt;  and  &lt;code&gt;construct&lt;/code&gt;  traps, requires the target to be a function.&lt;br&gt;&lt;br&gt;
With the apply and construct tarps you can do anything before the apply call or the  &lt;code&gt;new proxy()&lt;/code&gt;  is execute.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mcmtdjen--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/657/1%2AAgo3GublZxepyDnEsYIcFQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mcmtdjen--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/657/1%2AAgo3GublZxepyDnEsYIcFQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It so Powerful !!!&lt;br&gt;
&lt;a href="https://i.giphy.com/media/3o84sq21TxDH6PyYms/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3o84sq21TxDH6PyYms/giphy.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Cancel the Proxy
&lt;/h2&gt;

&lt;p&gt;By default when you create proxy, the proxy is bounded to its target since creation and for its entire existence.&lt;/p&gt;

&lt;p&gt;Sometime it can be useful to cancel this binding, like in cases of , for example if you expose Object api (by proxy of course) and the token is no longer valid- you can terminate the object api by canceling the proxy.&lt;/p&gt;

&lt;p&gt;A revocable proxy can be create like that:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let  targetObject  =  {  
   name:  "target"  
};
let {proxy, revoke}= Proxy.revocable(targetObject,  {});

console.log(proxy.name);        // "target"  
revoke();
console.log(proxy.name); // throw an error
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The Proxy.revocable- receives two parameters as any proxy- but return us the revoke function that give us the ability to cancel the binding to the target-&lt;br&gt;&lt;br&gt;
as we can see in the example.&lt;/p&gt;

&lt;p&gt;Let see a simple  &lt;a href="https://codesandbox.io/s/proxy-with-react-gxhdy?file=/src/App.js"&gt;example with react&lt;/a&gt;&lt;br&gt;
&lt;iframe src="https://codesandbox.io/embed/proxy-with-react-gxhdy"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;As you can see- with proxy you take the object to the next level: you can interact with the low level, validate before delete key in object , take object and append to it all array’s methods (this is needed to implement array’s rules) -&lt;a href="https://github.com/nzakas/understandinges6/blob/master/manuscript/12-Proxies-and-Reflection.md#the-array-problem"&gt;check it here&lt;/a&gt; , and more.&lt;br&gt;&lt;br&gt;
For more information, refere to &lt;a href="https://github.com/nzakas/understandinges6"&gt;Understanding es6&lt;/a&gt; book and the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy"&gt;MDN&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/k39w535jFPYrK/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/k39w535jFPYrK/giphy.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope you found this short article useful. Now go and take your objects to the next level !!!🚀🚀🚀&lt;/p&gt;

&lt;p&gt;Browser support… all the browser is  &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy#Browser_compatibility"&gt;supported&lt;/a&gt; (Except from old IE 😒)&lt;/p&gt;

&lt;p&gt;Thanks For Reading.&lt;br&gt;&lt;br&gt;
Yanai.&lt;/p&gt;

</description>
      <category>proxyapi</category>
      <category>es6</category>
      <category>javascript</category>
      <category>webapi</category>
    </item>
  </channel>
</rss>
