Metaprogramming is a programming technique that allows a program to treat another program’s data like its own data. For example, a program can be designed to read, generate, analyze, or modify other programs while running, as well as modify itself. A proxy is a feature of metaprogramming that enhances the behavior of a function by passing different functions as a parameter, essentially allowing developers to trick the JavaScript language.
In this article, we’ll learn how JavaScript proxies work, then we’ll build a weather forecasting application using JavaScript proxy objects. To follow along with this tutorial, you’ll need basic knowledge of JavaScript. Let’s get started!
- What is a proxy?
- Why should you use a proxy?
- How does a proxy work?
traps
method- Build a weather forecast app using a proxy
- Conclusion
What is a proxy?
A proxy acts as a layer between an operation object, or a handler
, and a target
object, which are used to intercept and redefine fundamental operations or traps
, like getting, setting, and defining properties. Proxy objects are commonly used to log property accesses, validate, format, sanitize inputs, and more.
A proxy()
object is a wrapper for a target
object, through which the properties of the target
object can be accessed and modified with the help of traps
. A proxy is used for two main goals, which guide how to actually use proxy objects:
- A proxy controls data before modifying the property of the
target
object - A proxy performs additional functionality when accessing the property of the
target
object
Why should you use a proxy?
We can use a proxy for the following operations:
- To have full control over data
- To ensure the correct behavior of objects or functions
- For REST API calls, validation of data, and monitoring asynchronous functions
- In type checking and revocable references
- For Implementing the DOM (Document Object Model) in JavaScript
How does a proxy work?
Proxy syntax
let proxy = new Proxy(target, handler);
target
and handler
are the two parameters passed to the proxy()
object:
target
: The original object you’d like to proxyhandler
: Contains methods that control the behavior of thetarget
object
The target
object is the wrapped object, the handler
is the function used on the target
object, and traps
methods are used inside the handler
to perform operations on the target
object.
traps
method
traps
are handler methods that are triggered when some actions are performed on the target
object through the proxy()
object. The traps
method can retrieve data from a RESTful API and then be used to validate, format, and store the RESTful data response into the target
object. Let’s take a brief look at some of the common traps
methods and how we can use traps
to validate RESTful API responses:
The set()
trap
The set()
trap is triggered whenever the property of the target
object is to be modified using the proxy()
object. It can be used to control the behavior of the target
object.
Let’s learn how to use the set()
trap to fetch data from an API, then validate the response data before we store the data in the target
object. As an example, we’ll demonstrate how to use the genderize.io API in JavaScript proxy objects, a free API that statistically predicts a male or female gender association of a given name using existing population ratios:
let person = { name: "", gender: "", probability: "", count: "" } const handler = { set(target, property, value) { fetch('https://api.genderize.io/?name='+value) .then(response => (response.json())) .then(data => { if (typeof value === 'string') { if(data.name !=='undefined'){ target['name']=data.name target['gender']=data.gender target[probability]=data.probability target[count]=data.count }else { target['name']='' target['gender']='' target[probability]='' target[count]='' } }else{ throw new TypeError('The value of "name" must be a string.') } }); } }; const proxyPerson = new Proxy(person, handler); proxyPerson.name ="popoola"
From the above example, the set()
trap is used to validate the name, fetch the gender, and then update the properties of the person
object with the data that we retrieve from the API.
The get()
trap
The get()
trap is triggered when the property of the target
object is to be accessed via the proxy()
object. There are many ways to use this trap; for one, we can use it to restrict access to certain properties or return only parts of the values.
Let’s demonstrate how we can use the get()
trap to return a custom value from the target
object:
let person = { name: "", gender: "", probability: "", count: "" } const handler = { get(target, property) { if(property==='userDetails'){ return`${target.name} is a ${target.gender}` }elseif(property==='userInfo'){ If (target.name==="Male"){ Return "the user is a man" }else{ Return " the user is a woman" } }else{ return target[property] } console.log(target[property]) return target[property]; } } const proxyPerson = new Proxy(person, handler); console.log(proxyPerson.userDetails); console.log(proxyPerson.gender);
The person
object does not have a property userDetails
and userInfo
. Therefore, we use the get()
trap to return a custom value based on the properties that we have for the person
object.
More traps
The list below includes the other traps
available from the proxy()
object:
construct
: Traps usage of the new operatorgetPrototypeOf
: Traps an internal call to[[GetPrototypeOf]]
setPrototypeOf
: Traps a call toObject.setPrototypeOf
isExtensible
: Traps a call toObject.isExtensible
preventExtensions
: Traps a call toObject.preventExtensions
getOwnPropertyDescriptor
: Traps a call toObject.getOwnPropertyDescriptor
Build a weather forecast app using a proxy
Requirements
To get your API key, visit https://openweathermap.org/api
and sign up. If you click on API key, you should see something like the image below:
To demonstrate how to use a JavaScript proxy object to build a REST client application, let’s create a weather forecast application that allows users to search for any address, then provides the weather details of the address.
Creating index.html
Create the index.html
page and add the following HTML code to it:
<!DOCTYPE html> <html> <head> <title></title> </head> <style> table { font-family: arial, sans-serif; border-collapse: collapse; width: 100%; } td, th { border: 1px solid #dddddd; text-align: left; padding: 8px; } tr:nth-child(even) { background-color:#dddddd; } </style> <body> <h1 style="text-align:center;"> Weather forecast </h1> <div style="float:left;width:300px;height:200px;background-coor:red;margin-left:50px"> <label>enter city name</label> <input type="text" value="" id="city" onchange="check('state')"><br> <label>enter state name</label> <input type="text" value="" id="state"onchange="check('country')"><br> <label>enter country name</label> <input type="text" value="" id="country"onchange="{proxyPerson.name ='load'}"> <br> <input type="submit" id="load" onclick ="{proxyPerson.name}" value="weather forecast"> </div> <div style="float:right;width:300px;height:200px;background-coor:red;margin-right:50px;"> <table> <tr> <td>location</td> <td><span id="location"></span></td> </tr> <tr> <td>Status</td> <td><span id="status"></span></td> </tr> <tr> <td>Description</td> <td><span id="description"></span></td> </tr> <tr> <td>Pressure</td> <td><span id="pressure"></span></td> </tr> <tr> <td>Humidity</td> <td><span id="humidity"></span></td> </tr> <tr> <td>temperature </td> <td><span id="temperature"></span></td> </tr> </table> </div> </body> <script type="text/javascript" src="proxy.js"></script> </html>
The code above is the interface; it has three input fields where users will enter a city
, state
, and country
to retrieve weather forecasts for the city.
Creating proxy.js
Now that our interface is ready, let’s create a proxy.js
file, which will contain all the functionality of the application. Add the following code to proxy.js
:
function check(id){ document.getElementById(id).value =""; } let location = { name: "", lat: "", lon: "" } const handler = { set(target, property, value) { let apikey = '0abe276c48b3362cd8a7950b9382ee37' let city = document.getElementById("city").value; let state = document.getElementById("state").value; let country = document.getElementById("country").value; if(city!="" && state!="" && country !=""){ fetch('https://api.openweathermap.org/geo/1.0/direct?q='+city+','+state+','+country+'&limit=1&appid='+apikey ) .then(response => (response.json())) .then(data => { target\['name'] = data[0\]['name'] target\['lat'] = data[0\]['lat'] target\['lon'] = data[0\]['lon'] console.log(target['lat']) }); }else { alert("please enter a valid location ") } }, get(target, property) { let apikey = '0abe276c48b3362cd8a7950b9382ee37' let lat = target['lat']; let lon = target['lon']; if(lat!=""&& lon!=""){ fetch('https://api.openweathermap.org/data/2.5/weather?lat='+lat+'&lon='+lon+'&appid='+apikey) .then(response => (response.json())) .then(data => { document.getElementById("location").innerHTML = data['name']; document.getElementById("description").innerHTML = data\['weather'\][0]['description'] document.getElementById("status").innerHTML = data\['weather'\][0]['main'] let icon = data\['weather'\][0]['icon'] document.getElementById("temperature").innerHTML = data\['main'\]['temp'] document.getElementById("pressure").innerHTML = data\['main'\]['pressure'] document.getElementById("humidity").innerHTML = data\['main'\]['humidity'] }); }else{ alert("please enter a valid location") } } }; const proxyPerson = new Proxy(location, handle)
When creating the proxyPerson
object, we pass in the location
object as the original object that we want to proxy. We then pass in a handler
object as the second argument, which controls the behavior of the location
object.
We use the set()
trap to retrieve the user’s address from the city, as well as the input fields for state and country. Then, we send a request to the openweathermap.org
endpoint to get the address’s latitude
and longitude
. Finally, we update the location
object’s properties with the city name
, latitude
, and longitude
. We obtain the latitude
and longitude
from the location
object using the get()
trap, then fetch the weather details from the openweathermap.org
endpoint, and finally display the weather details on the page.
Conclusion
In this article, we leaned what proxies are and how they function, exploring some typical proxy traps, and finally building a weather forecast application using JavaScript proxy objects. Hopefully, you have a better understanding of how proxy objects in JavaScript can improve your code. I hope you enjoyed this tutorial! Please leave a comment if you have any questions.
The post How to build a REST client with JavaScript proxies appeared first on LogRocket Blog.
from LogRocket Blog https://ift.tt/wD9GosL
via Read more