{"id":5341,"date":"2015-08-16T22:08:36","date_gmt":"2015-08-17T05:08:36","guid":{"rendered":"http:\/\/g-liu.com\/blog\/?p=5341"},"modified":"2015-08-16T22:08:36","modified_gmt":"2015-08-17T05:08:36","slug":"object-oriented-programming-javascript-using-pojos-for-good","status":"publish","type":"post","link":"https:\/\/g-liu.com\/blog\/2015\/08\/object-oriented-programming-javascript-using-pojos-for-good\/","title":{"rendered":"Object-Oriented JavaScript: Using POJOs for good"},"content":{"rendered":"<p>JavaScript <a href=\"http:\/\/stackoverflow.com\/questions\/5852583\/is-javascript-an-object-oriented-language\" class=\"broken_link\" rel=\"nofollow\">may not be the poster child of object-oriented programming languages<\/a>, but that doesn&#8217;t mean you can&#8217;t take advantage of OO principles in your JS app. Plain Old JavaScript Objects, or POJOs, can be a lifesaver when working with complex datasets and databases. They&#8217;re easy to set up, and have many use cases such as normalizing data, handling faulty responses, and storing derived properties.<\/p>\n<p>This post&nbsp;assumes basic knowledge of an object-oriented programming language, such as Java or C++. If you have not worked with classes and objects before, I recommend quickly <a href=\"http:\/\/docs.oracle.com\/javase\/tutorial\/java\/concepts\/object.html\">reading up<\/a>&nbsp;on OOP before reading this post further.<\/p>\n<p><!--more--><\/p>\n<h1>JavaScript 101: How to POJO<\/h1>\n<p>As with all things in JavaScript, there are multiple ways to create a JavaScript object. The one I prefer is <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Guide\/Working_with_Objects#Using_a_constructor_function\">defining a constructor function<\/a>.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nfunction CarData(make, model, year, condition) {\r\n    this.make = make;\r\n    this.model = model;\r\n    this.year = year;\r\n    this.condition = condition;\r\n}\r\n\r\nvar myToyotaCorolla = new CarData('Toyota', 'Corolla', 2014, 'new');\r\nconsole.log(myToyotaCorolla.make);  \/\/ -&gt; 'Toyota'\r\n<\/pre>\n<p>Note the usage of the&nbsp;<code>new<\/code> keyword. This is the quintessential keyword that lets us create new instances of a &#8220;class&#8221;. Each class can have separate properties associated with it. For example, I can create a <code>new CarData('BMW', '320i', 2015, 'new);<\/code> and <code>new CarData('Jeep', 'Cherokee', 2010, 'used');<\/code>, which could for example represent the cars in my garage.<\/p>\n<h1>When to use POJOs<\/h1>\n<p>In general,&nbsp;POJOs are a lifesaver when dealing with any sort of structured data. POJOs and JSON especially go hand-in-hand; after all JSON does stand for JavaScript <i>Object<\/i>&nbsp;Notation. If your server responds with a different content type, like XML or even CSV, POJOs are still extremely useful, given a bit more data massaging.<\/p>\n<h2>You want to standardize data from a server or API<\/h2>\n<p>I was working with a REST API&nbsp;which returned data about the inventory of a car dealership. When querying the API, the response looked like this:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\ncriteria: {\r\n    category: &#x5B;&quot;NEW&quot;],\r\n    make: &#x5B;&quot;BMW&quot;],\r\n    model: &#x5B;&quot;320i&quot;, &quot;325xi&quot;, &quot;M4&quot;],\r\n    year: &#x5B;&quot;2015&quot;, &quot;2014&quot;]\r\n},\r\nactive: &quot;YES&quot;\r\n<\/pre>\n<p>This data is fine to work with, but what if:<\/p>\n<ul>\n<li>You want to rename the &#8220;<code>category<\/code>&#8221; key to &#8220;<code>condition<\/code>&#8221; because it makes more sense<\/li>\n<li>You want to lowercase the <code>make<\/code> array for comparison purposes, <em>and<\/em> name it <code>makes<\/code> (after all, it&#8217;s an array)<\/li>\n<li>You might be querying multiple APIs, some which use different terminology than others to label certain values<\/li>\n<\/ul>\n<p>Let&#8217;s face it, APIs can be less than perfect with the format of data that they return. Furthermore, you don&#8217;t always have complete control over what kind of data, and how the data is sent to your client. This is where the power of client-side processing comes in. Consider the following POJO:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/**\r\n * @param serverData {object} raw response from server; see above\r\n *\/\r\nfunction InventoryData(serverData) {\r\n    this.conditions = serverData.criteria.category;\r\n    this.makes = serverData.criteria.make;\r\n    this.models = serverData.criteria.model;\r\n    this.years = serverData.criteria.year;\r\n\r\n    for (var i = 0; i &lt; this.conditions.length; i++) {\r\n        this.conditions&#x5B;i] = this.conditions&#x5B;i].toLocaleLowerCase();\r\n    }\r\n    for (var i = 0; i &lt; this.makes.length; i++) {\r\n        this.makes&#x5B;i] = this.makes&#x5B;i].toLocaleLowerCase();\r\n    }\r\n    for (var i = 0; i &lt; this.models.length; i++) {\r\n        this.models&#x5B;i] = this.models&#x5B;i].toLocaleLowerCase();\r\n    }\r\n    for (var i = 0; i &lt; this.years.length; i++) {\r\n        this.years&#x5B;i] = parseInt(this.years&#x5B;i], 10);\r\n    }\r\n\r\n    this.active = (serverData.active === &quot;YES&quot;);\r\n}\r\n<\/pre>\n<p>When this function is <code>new<\/code>ed, it will do several things:<\/p>\n<ul>\n<li>Flatten out the <code>criteria<\/code> and <code>active<\/code> keys, so that they are on the same hierarchy<\/li>\n<li>Lowercase the <code>make<\/code>, <code>model<\/code>, and <code>category<\/code> arrays from the server, for easier case-insensitive comparison later on<\/li>\n<li>Convert the <code>year<\/code> array from strings to integers<\/li>\n<li>Convert the <code>active<\/code> value from a string to a representative boolean<\/li>\n<\/ul>\n<p>In the function where I handle the API response, I would do the following:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nfunction handleAPIResponse(dataJSON) {\r\n    var inventoryData = new InventoryData(dataJSON);\r\n    inventoryService.storeInventoryData(inventoryData);\r\n}\r\n<\/pre>\n<p>Somewhere later I may have a function that takes a user&#8217;s input and sees if it matches any models in the dealership&#8217;s inventory. Since I&#8217;ve standardized all of the data from the API, it&#8217;s very easy to compare against my POJO.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nfunction searchForModel(userInput) {\r\n    var searchCriteria = userInput.toLocaleLowerCase();\r\n    var inventoryData = inventoryService.getInventoryData();\r\n\r\n    \/\/ This line is made possible by the fact that my POJO standardizes all models to be lowercase.\r\n    \/\/ I can then use built-in indexOf to find what the user is looking for\r\n    return inventoryData.models.indexOf(searchCriteria);\r\n}\r\n<\/pre>\n<p>And we are just getting started! The POJO defines what we call a contract, an enforced set of rules between the the developer and the client. This POJO promises that &#8212; as long as the API does its job in returning data without error &#8212; all makes, models, and conditions will be lowercased, all years will strictly be integers, and the <code>active<\/code> field will be a boolean. This contract makes it much easier for the developer to work with the data later on.<\/p>\n<p>If you are working with data returned in a format other than JSON, no fear! POJOs are still just as valid to use. For XML data, JavaScript has <a href=\"http:\/\/stackoverflow.com\/questions\/17604071\/parse-xml-using-javascript\" target=\"_blank\" class=\"broken_link\" rel=\"nofollow\">methods to deal with DOM manipulation<\/a>. Plain text? Take a look at JavaScript&#8217;s many built in <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/String?redirectlocale=en-US&#038;redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FString\" target=\"_BLANK\">String methods<\/a>.<\/p>\n<h2>You want to work with derived properties<\/h2>\n<p>In the previous example, I copied the data from the server response, more or less. But look closely, and notice that the server response contains more useful data that is not explicitly written. I determine that later on, I want to know how many models the dealership has. I can add a property to my POJO like so:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nfunction InventoryData(serverData) {\r\n    this.modelCount = serverData.model.length;\r\n    \/\/ ... the rest\r\n}\r\n<\/pre>\n<p>If I&#8217;m using a framework like Angular, I can display the data in the view like so:<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n{{inventoryData.modelCount}} model(s) available -- visit today!\r\n<\/pre>\n<p><code>modelCount<\/code> is what I call a <strong>derived property<\/strong>, a property able to be obtained from analysis. With more complex datasets, storing derived properties once can improve the runtime when averaged over many accesses. In this example, accessing the length of an array may be a trivial operation, but more complex use cases such as counting letter occurrences in a DNA string can definitely benefit from introducing derived properties in a POJO.<\/p>\n<h2>You want to guard against undefined values<\/h2>\n<p>Some of the APIs I work with do not have a well-defined specification. When I query for data, some of their data may be or completely missing. Suppose we were querying a weather forecasting API, and got the following response:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n{\r\n    temp_now: 75,\r\n    temp_hi: 89,\r\n    wind_speed: &#x5B;12],\r\n    wind_chill: undefined\r\n}\r\n<\/pre>\n<p>Normally, I would also expect a low temperature, a wind direction (as <code>wind_speed[1]<\/code> in the server response), and a <code>wind_chill<\/code>. Unfortunately, the server failed to provide the data. But I do not want to take its defaults. Instead, I define my own.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/\/ different syntax, still a valid way to define a POJO\r\nvar WeatherData = function (serverData) {\r\n    this.temp_now = serverData.temp_now || null;\r\n    this.temp_hi = serverData.temp_hi || null;\r\n    this.temp_lo = serverData.temp_lo || null;\r\n\r\n    this.wind_speed = serverData.wind_speed&#x5B;0] || 0;\r\n    this.wind_direction = serverData.wind_direction&#x5B;1] || undefined;\r\n\r\n    this.wind_chill = serverData.wind_chill || 0;\r\n}\r\n<\/pre>\n<p>For those not familiar with the notation <code>var foo = A || B<\/code>, <code>foo<\/code> gets <code>A<\/code> if <code>A<\/code> <a href=\"https:\/\/dorey.github.io\/JavaScript-Equality-Table\/\" target=\"_BLANK\">is not falsy<\/a>; <code>B<\/code> otherwise.<\/p>\n<p>Now, the temperatures are set to <code>null<\/code> when the API does not include them in the response, wind speed is assumed 0 if not provided, wind direction is (intentionally) set to <code>undefined<\/code> if not provided, and wind chill is assumed 0 if not provided. If we were to display, say, the wind speed and wind chill on a weather app, the value &#8220;0&#8221; looks a whole lot nicer than &#8220;<code>null<\/code>&#8221; or &#8220;<code>undefined<\/code>&#8220;. For temperature, we should not have a default of <code>0<\/code> since that is a valid temperature value. Instead, we may use something of the sort: <code>displayedTemp = weatherData.temp_now || \"Could not fetch temperature\";<\/code>.<\/p>\n<h2>You want to validate the data on the client side<\/h2>\n<p>Validating data is a huge part of computer security, and can guard against nefarious things such as Cross-Site Scripting (XSS) and SQL injection. It is also important if you want to keep an application from unexpectedly crashing due to some invalid data read in from 1000 lines ago. POJOs can handle invalid data in multiple ways: by standardizing it away as seen in the first use case, or by throwing exceptions.<\/p>\n<p>Consider an electronic payment service, which stores users&#8217;, SSNs credit card numbers, and other validatable information. We know this service is usually reliable in its validation, but just as an extra layer of security, we want to validate client-side. On one occasion, the service responds with this dataset:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n&#x5B;{\r\n    name: &quot;John Q. Public&quot;,\r\n    ccnum: 4441009065488719,\r\n    ssn: 532146564\r\n}, {\r\n    name: &quot;Not A. Scammer&quot;,\r\n    ccnum: 1111111111111112,\r\n    ssn: 1234567890\r\n}]\r\n<\/pre>\n<p>Our POJO for handling the data could look like this.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/\/ Also demonstrates the use of multiple POJOs in conjunction with one another\r\nvar PaymentDataList = function(serverData) {\r\n    this.paymentData = &#x5B;];\r\n    for (var i = 0; i &lt; serverData.length; i++) {\r\n        this.paymentData.push(new PaymentData(serverData&#x5B;i]));\r\n    }\r\n}\r\n\r\nvar PaymentData = function(pData) {\r\n    \/\/ Do some validation first\r\n    if (pData.ccnum) {\r\n        \/\/ the Luhn algorithm is used as one means of validating credit card numbers\r\n        if (checkAgainstLuhnAlgorithm(pData.ccnum)) {\r\n            \/\/ for the sake of simplicity, assume valid\r\n            this.ccnum = pData.ccnum;\r\n        } else {\r\n            throw new Exception(&quot;Invalid credit card number&quot;);\r\n        }\r\n    } else {\r\n        throw new Exception(&quot;No credit card number given!&quot;);\r\n    }\r\n\r\n    if (isValidSSN(pData.ssn)) {\r\n        this.ssn = pData.ssn;\r\n    } else {\r\n        throw new Exception(&quot;Invalid Social Security Number!&quot;);\r\n    }\r\n}\r\n<\/pre>\n<p>In the code to handle the response from the service:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nfunction handleServiceResponse(serviceData) {\r\n    var paymentDataList;\r\n    try {\r\n        paymentDataList = new PaymentDataList(serviceData);\r\n    } catch (e) {\r\n        paymentDataList.length = 0;\r\n        console.err(e);\r\n        \/\/ terminate the program or do whatever is necessary to keep running\r\n    }\r\n}\r\n<\/pre>\n<p>Now your application is immune to scammers trying to use invalid credit cards for payment. In the real world, the developer may create different kinds of <code>Exceptions<\/code>, or defer from throwing exceptions at all and attempt to continue the program, with all invalid data being sanitized.<\/p>\n<h1>Using POJOs dynamically<\/h1>\n<p>So far, I have only discussed using POJOs as storage objects. They are set once, and accessed many times thereafter with no modification to the original contents. Writing data to a POJO more than once is a completely valid use case, especially if your application allows users to update data. JavaScript POJOs can indeed have functions.<\/p>\n<p>Recall my second example (derived properties in a POJO), where I derived a property:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nfunction InventoryData(data) {\r\n    this.makes = data.make;\r\n    this.makesCount = this.make.length;\r\n}\r\n<\/pre>\n<p>The problem here is, if I add a make to my POJO, <code>makesCount<\/code> does not update properly. It is set once and never touched again.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar invData = new InventoryData(serverData);\r\nexpect(invData.makesCount).toEqual(3);  \/\/ assume true\r\ninvData.makes.push(&quot;Mazda&quot;);\r\nexpect(invData.makesCount).toEqual(4);  \/\/ fails!\r\n<\/pre>\n<p>On the other hand, we can turn <code>makesCount<\/code> into a function, as in the following setup:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nfunction InventoryData(data) {\r\n    this.makes = data.make;\r\n    this.getMakesCount = function () {\r\n        return this.makes.length;\r\n    }\r\n}\r\n<\/pre>\n<p>Then you would call <code>invData.getMakesCount()<\/code>. A small change, but now you have a dynamic accessor in your POJO.<\/p>\n<h2>What about mutators and setters?<\/h2>\n<p>If you want to take your POJOs to the next level of OO abstraction, then you can introduce mutators\/setters alongside your getter methods. In order for setters to make sense in your POJO, you would have to declare the appropriate fields as private. Otherwise clients would simply set the variable directly, e.g. <code>this.makes = [...]<\/code> as opposed to <code>this.setMakes([...])<\/code>. Douglas Crockford <a href=\"http:\/\/www.crockford.com\/javascript\/private.html\" target=\"_BLANK\">discusses private members in detail<\/a>, and I encourage you to read up on it.<\/p>\n<h1>A word about POJOs, regular Objects, and Jasmine<\/h1>\n<p>I was bamboozled a few weeks ago when writing a Jasmine test that involved the use of POJOs. Writing out a JavaScript object and constructing one will cause <code>toEqual()<\/code> to fail! Consider the simple case:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar GNum = function (value) {\r\n   this.value = value;\r\n};\r\n\r\n\/\/ test it\r\nit('Will fail in 1.2, but not earlier versions', function () {\r\n    var expected = {\r\n        value: 1\r\n    };\r\n    var actual = new GNum(1);\r\n    expect(actual).toEqual(expected);  \/\/ fail!\r\n});\r\n<\/pre>\n<p>The reason why is that Jasmine will compare the constructors of the two objects <code>actual<\/code> and <code>expected<\/code>. They are different in this case. You can <a href=\"http:\/\/stackoverflow.com\/questions\/31599143\/jasmine-spy-expects-to-be-called-with-object\" target=\"_BLANK\" class=\"broken_link\" rel=\"nofollow\">read more on my StackOverflow post<\/a>.<\/p>\n<h1>Wrap-up<\/h1>\n<p>Introducing POJOs turned out to be a game-changer in our app. I hope this post will help you learn to love the abstraction and simplification POJOs can bring to your app as well. In short, use POJOs to<\/p>\n<ul>\n<li>Standardize data<\/li>\n<li>Store derived properties<\/li>\n<li>Guard against undefined values<\/li>\n<li>Validate data<\/li>\n<li>Abstract getters and setters for a dataset<\/li>\n<\/ul>\n<p>There are of course many other use cases, but this post should cover the basics. If you have an interesting use case, let me know in the comments!<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content --><!-- AddThis Related Posts generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>JavaScript may not be the poster child of object-oriented programming languages, but that doesn&#8217;t mean you can&#8217;t take advantage of OO principles in your JS app. Plain Old JavaScript Objects, or POJOs, can be a lifesaver when working with complex datasets and databases. They&#8217;re easy to set up, and have many use cases such as normalizing data, handling faulty responses, &#8230;<!-- AddThis Advanced Settings generic via filter on wp_trim_excerpt --><!-- AddThis Share Buttons generic via filter on wp_trim_excerpt --><!-- AddThis Related Posts generic via filter on wp_trim_excerpt --><\/p>\n","protected":false},"author":2,"featured_media":5353,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"footnotes":"","jetpack_publicize_message":"Object-Oriented #JavaScript: Using POJOs for good","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[830],"tags":[],"jetpack_publicize_connections":[],"aioseo_notices":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/g-liu.com\/blog\/wp-content\/uploads\/2015\/08\/shipping-containers-china.jpg","jetpack_shortlink":"https:\/\/wp.me\/p2Zt3y-1o9","_links":{"self":[{"href":"https:\/\/g-liu.com\/blog\/wp-json\/wp\/v2\/posts\/5341"}],"collection":[{"href":"https:\/\/g-liu.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/g-liu.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/g-liu.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/g-liu.com\/blog\/wp-json\/wp\/v2\/comments?post=5341"}],"version-history":[{"count":11,"href":"https:\/\/g-liu.com\/blog\/wp-json\/wp\/v2\/posts\/5341\/revisions"}],"predecessor-version":[{"id":5355,"href":"https:\/\/g-liu.com\/blog\/wp-json\/wp\/v2\/posts\/5341\/revisions\/5355"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/g-liu.com\/blog\/wp-json\/wp\/v2\/media\/5353"}],"wp:attachment":[{"href":"https:\/\/g-liu.com\/blog\/wp-json\/wp\/v2\/media?parent=5341"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/g-liu.com\/blog\/wp-json\/wp\/v2\/categories?post=5341"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/g-liu.com\/blog\/wp-json\/wp\/v2\/tags?post=5341"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}