JavaScript has changed a lot these last couple of years. To begin with, JavaScript was never given a proper place within the UI development stack, and the confusion between Java and JavaScript in the early years didn’t help. In the following 3 articles about JavaScript, I am going to try to refactor starting from the simple, legacy JavaScript code to using two of the most used JavaScript design patterns: The Module Design Pattern and the Module Reveal Pattern. Hopefully, these step by step instructions and seeing how the code evolve will help you understand the “why” is now the norm to create Object Oriented JavaScript code and adhere to design pattern practices when coding.
The project is a simple MVC Core Web Application project created using Visual Studio 2015. It just serves as a canvas for the one-page JS code that will be served to the user. My example is also a very basic one, lacking any logging or error trapping. The main idea is after all to understand the progression of the JavaScript code.
This series of refactoring using Module design pattern has 3 parts:
- Refactoring JavaScript Legacy to Object Oriented (this page)
- Refactoring Using the Module Design Pattern
- Refactoring using the Module Reveal Design Pattern
The Home Controller
The Home controller just displays the 4 different pages, each showing a different pattern of JavaScript coding.
public class HomeController : Controller { public IActionResult Index() { return View(); } public IActionResult Index1() { return View(); } public IActionResult Index2() { return View(); } public IActionResult Index3() { return View(); } }
The Layout File (Navigation Bar)
The layout file shows the navigation bar that will help us load each of the pages required for this exercise. Again, nothing out of the ordinary.
<div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li> <li><a asp-area="" asp-controller="Home" asp-action="Index1">Object Pattern</a></li> <li><a asp-area="" asp-controller="Home" asp-action="Index2">Module Pattern</a></li> <li><a asp-area="" asp-controller="Home" asp-action="Index3">Module Reveal Pattern</a></li> </ul> </div>
JavaScript (“The Very Old Way of Coding JS”)
And finally, the JavaScript code. The example is a very basic stock of apples, the UI gives the user the opportunity to add and sell apples, which increase and decrease the total number of apples in the stock respectively, and another button to display the amount of apples in stock. Our first try shows the way JavaScript was coded many years ago and while effective, is no longer the norm.
@{ ViewData["Title"] = "Home Page"; } <script type="text/javascript"> var stockApples = 0, msgInStock = "Yes, we have apples in stock.", msgOutOfStock = "No, we don't have apples in stock."; function addToStock(count) { stockApples += count; } function currentStock() { return stockApples; } function displayCurrentStock() { $("#customerFeedback").text("Current number of apples in stock: " + stockApples); } function addApples() { var number = parseInt($("#numberOfAddApples").val()); stockApples += number; } function sellApples() { var numberSold = parseInt($("#numberOfSoldApples").val()); stockApples -= numberSold; } </script> <div id="content"> <p> <label for="numberOfAddApples">Number of Apples to Add:</label> <input type="text" id="numberOfAddApples"/> <button id="addApples" onclick="addApples()">Add</button> </p> <p> <label for="numberOfSoldApples">Number of Apples Sold:</label> <input type="text" id="numberOfSoldApples"/> <button id="sellApples" onclick="sellApples()">Sell</button></p> <p><button id="btnCurrentStock" onclick="displayCurrentStock()">Display Current Stock</button><br /></p> <h4>Customer Feedback:</h4> <span id="customerFeedback"></span> </div>
As you can see, within the <script> tags all the code is public and there is no notion of scope, private or public methods and variables. Does it work? Absolutely.
Refactoring to JavaScript Objects
Let’s try to refactor this legacy way of writing code to an object oriented approach in JavaScript. Just a small addition is all you need to make this code an object. Let’s see.
<script type="text/javascript"> var s = { stockApples: 0, msgInStock: "Yes, we have apples in stock.", msgOutOfStock: "No, we don't have apples in stock.", addToStock: function (count) { this.stockApples += count; }, currentStock: function () { return this.stockApples; }, displayCurrentStock: function () { $("#customerFeedback").text("Current number of apples in stock: " + this.stockApples); }, addApples: function () { var number = parseInt($("#numberOfAddApples").val()); this.stockApples += number; }, sellApples: function () { var numberSold = parseInt($("#numberOfSoldApples").val()); this.stockApples -= numberSold; } } </script> <div id="content"> <p> <label for="numberOfAddApples">Number of Apples to Add:</label> <input type="text" id="numberOfAddApples" /> <button id="addApples" onclick="s.addApples()">Add</button> </p> <p> <label for="numberOfSoldApples">Number of Apples Sold:</label> <input type="text" id="numberOfSoldApples" /> <button id="sellApples" onclick="s.sellApples()">Sell</button> </p> <p><button id="btnCurrentStock" onclick="s.displayCurrentStock()">Display Current Stock</button><br /></p> <h4>Customer Feedback:</h4> <span id="customerFeedback"></span> </div>
You can see a couple of things: all the JavaScript code now is contained within that single object “s”. “s” is now similar to a class in C#, with properties and methods. Second, the “onclick” actions had changed a bit, now they need to call the function within the object like this: “s.addApples()” for example.
In the next article, we are going to keep refactoring this single object using the Module Design Pattern: Refactoring using the Module Design Pattern