JavaScript MVC with ku4webApp

There is no doubt that front-end web has had enormous demands placed on it in recent years. Users expect quick, responsive and powerful front-end web apps that allow them to do things that wouldn’t even be expected from native applications even a few years ago. With those expectations come demands from executives, management, and clients for developers to provide these experiences.

The predicament that developers all too often, if not always, find themselves in, is that rapidly providing these interfaces and experiences causes their code to get rather unwieldy very quickly. To combat this, developers have to spend more time and effort architecting, not only an immediate solution, but also soothsaying what the future will hold. This quickly burns up hours of ever valuable and sometimes unavailable time, leaving them with a choice: architect a maintainable, tested system that not only supports intelligent change, but also encourages it; or slam something together and get it out the door, then “come back later” to “fix” the issues that will go live with the release of this new code.

In today’s article we are going to look at a system that doesn’t force this choice. It is a system that allows developers to forego the constant reinventing of the wheel and focus on building excellent web apps that are inherently well architected and intrinsically rooted in quality atop a unit tested foundation.

Introducing: ku4webApp

ku4webApp is a front-end JavaScript MVC architecture that allows wildly rapid development, while enforcing maintainability. ku4webApp is the foundation of a number of greatly successful projects. Today, we will take a look at it, and, hopefully, help some of you find a tool that will make your already hectic dev life, a little easier.

The ku4webApp front-end, JavaScript MVC architecture leverages the ku4* suite and simplifies a Model-View-Controller design of front-end web applications. If you don’t know, MVC has been around for a long time, long before the development of JavaScript. Hell, long before the web. This proven pattern has, certainly, withstood the test of time, and during its tenure it has been re-hashed, re-branded and re-produced endlessly, but at the end of the day, under all of the pomp and circumstance, every one of these superficial remakes are all simply MVC! So, I’ll make no bones about it. ku4webApp is MVC. It’s not MVVM, MGTV, LMNOP, QRS, or TUV — it’s MVC. The rest of this article will assume at least a high-level knowledge of MVC. So, if for you, MVC was no more than three English consonants before you started reading this, you may find the following a difficult read. — Okay, you have been warned. Let’s get started!

As with any MVC architecture we will want to define our Models our Views and our Controllers, but before we get to that, we need to grab the latest ku4js-webApp from Github and set up our new ku4webApp project.

You can grab the current ku4webApp source from Github and store it wherever makes sense for your directory, file, and source management conventions. (The use of Github or any discussions of directory, file and source management are outside the scope of this document. You can investigate these topics further through Github documentation and other 3rd party resources.) 

Project Setup

Okay, now that we have the ku4webApp source, let’s first set up our project directory structure. With ku4webApp this is always the same and it is crazy simple to create. We simply copy and past the _Template directory to where we want our new ku4webApp project to live.

Image

Done. :{)}

And there we have it. Our MVC directory structure is setup and ready to go. Now, let’s personalize this project. Today, we are going to assume that we are going to write a simple and contrived eCommerce system.

First, we rename it from _Template to ku4eCommerce (or whatever you like)

Image

 

Then, we update our build scripts to include our new project name. (Though you will likely favor or even only use one, it is wise to update both of these files for any future event that developers who favor other systems work on your project).

For Mac
Image

For Windows
Image

And we will rename the -ProjectFiles- directory to the name of our project as well.

Image

We will name ours ku4eCommerce. (It is wise to use the same name as you did in your build files, simply to reduce the likelihood of future confusion.)
Image

I should note that, though the names that you have just updated will have implications on the system, in that they will play a role the name of your project output files and the paths where you will find your resources, they are in no way interdependent. I repeat, you can name these items anything you want, and you can name them all something different. Your project will not break if you do. Though, I must say that I do recommend against this as it can cause confusion later.

Okay, our project is setup. Let’s develop our model!

Model

Our model will live in the /src/ku4eCommerce/models/ directory. This directory will contain our business logic and the service layer to communicate with the back-end. As we’ve already said, we are writing the front-end for an eCommerce site. So, our model will include the following:

Products,
Promotions,
Payment,
and Logistics

It only makes logical sense, then, to create these models in our system. So let’s add them to our /src/ku4eCommerce/models/ directory.

You will notice when you open the /src/ku4eCommerce/models/ directory for the first time, there is a model.js.readme file in there. This file is not needed. It is simply there for an example. You can rename it and use it if you like, or you can just delete it. It does contain a model class skeleton that is useful when you are just starting out, but the ku4webApp system is not dependent on it. Because we are just starting out, I will keep it and copy code from it later. So you may want to keep yours, too! :{)}

Image

Next, let’s configure our services.

Services

We are going to assume that our system is not a closed system and will need to talk to a server. We are going to encapsulate our communication in a service layer so that we don’t garb-up the business logic of our system with a bunch of communication overhead. ku4webApp has a straight forward and simple service configuration system that is found at /src/config.services.js. This config contains a skeleton for you to use to set up your services. We will use this skeleton to set up our first products service.

Image

Using our skeleton, we fill out the necessary components

Image

As you can see, this service configuration requires a name, a verb with which to call the server, a URI where the service is found, and two callbacks. success and error. You can name these callbacks whatever you would like. I, personally, like the “svc+” and “svc-” convention indicating a service success and a service error.

The “Product” Model

Now that we have our product service set up, let’s implement the product model. If you haven’t deleted it, you can copy the skeleton from the model.js.readme file to get started.

Image

Looking at this skeleton, you can wee that in every ku4webApp model you can/will:

  • Implement custom methods that your controller will call.
  • Have access to service methods via this.$service(“[serviceName]”).
  • Be able to subscribe to the callbacks that your services provide.
  • Have access to ku4collections via this.$collection(“[collectionName]”). (These collections leverage the NoSQL collections of ku4js-data)
  • Be able to notify your views of state changes using this.$notify([optional arguments]. “notificationName”).

With this knowledge, let’s set up our product model to be able to get products from the server, and notify our view when this has happened.

Image

Here we  have created a model named “products” and implemented a listProducts method, on line 11, that calls the service that we configured a moment ago. We then subscribe to that very service’s callbacks, on lines 22 & 23.

Okay, let’s get this model unit tested.

Unit Testing

ku4js-webApp ships with Qunit as the Unit testing framework. You can use any framework that you like, but for this example we will use Qunit.

First thing’s first, create the test file and implement a ‘new’ class test to ensure that we can access products.

Image

Here we create a Qunit testing module, name it ‘models.products’, set up the ku4webApp test bundle and implement a test for retrieving an instance of our products model.

ku4webAppUT Bundle

The ku4webAppUT bundle (a.k.a test bundle) will be necessary in every one of your model tests, and, as we will see later, other tests, too. It will give you access to important items needed for testing. First, you get a bundle that you can ask to give you instances of your model classes. Second, it gives you access to the mediator that handles the communication within your ku4webApps. Lastly, it allows you to configure error handling to throw, log or silence errors.

The last thing to do to wrap up our unit test is include this unit test in our gui.htm file. To do this, simply go to the /test/gui.htm file and include the unit test script file as shown on line 13. While you are here add a reference to the build artifact that we will create in the next step as shown on line 11.

Image

Alright, we are wired-up. Next, we will build our project so that we can unit test our product class

Building your project

Building is simple. Just execute the appropriate built script for your system.

Image

When you have done this, the build artifacts will appear in the /bin directory. You will get a compressed and uncompressed version of the file. You should use the compressed version in production. The uncompressed version is useful for debugging and is the version that is already wired up with your unit tests.

After you have compiled you will open a browser, navigate to your unit test gui.htm and see your first test pass.

Image

Great! Now you are building a maintainable, unit tested MVC project! Next up, we can implement a test for our product model’s listProducts method.

More on Unit Tests

It’s pretty common, and recommended, to have your model operate on entities, read and write them to collections, and manage all server communications. It really shouldn’t do much, if any, more than that. Too, both your classes and their methods should have very specific concerns and objectives. This means that your Unit Tests should follow suit and test one very specific feature, one unit, if you will. Unit tests should be concise.

Because our unit tests should be concise, we will want to make sure that we are not testing any functionality outside of the unit that we are currently testing. In this next part we are going to test a model function across a server call and we do not want to test the server itself. To do so would be antithetical to aim the unit test.  We should only test the model to ensure that it functions as expected with expected input. This is where our test bundle comes in crazy handy. As we will see in one moment, it allows us to dictate what the model will get on the server callback, so that we can isolate the unit test and see how our model responds with a given input.

For example, let’s say that we expect our server to respond to listProducts requests with a JSON array of products, where a product is defined as follows:

var product = {
 "id": "UID",
 "categoryId": "UID",
 "sku": 0, //Some number
 "name": "STRING",
 "imageUrl": "URL"
 "price": 0 //Some number
};

This means that our model should expect to get an array of these objects from the server. That said, our call to our model takes zero arguments, and since we are not calling a server, how will we get back this data, for our unit test? Enter bundle.callback!

bundle.callback

bundle.callback is yet another one of the utilities offered to us by ku4webAppUT. This method allows us to set a function that we control as the method that the service will call. Any arguments that the server passes, be them query strings, post parameters, JSON or other will be passed to this function. What the function does with this information is up to you, but know that this function’s return value will be passed to your model’s subscriber method for that service! This means that you can create tests for situations where you get back good data, bad data, null data, etc, all while isolating your model so that you can test how it responds to these situations without incorrectly including unnecessary external items such as network communication or server methods into your unit test! Pretty sweet, right?! :{)}

Alright, let’s write a test for this case.

Image

And run it.

Image

Excellent! We are now unit testing units of our models that need callback data from the server, all while isolating those very calls from the server itself! Isolated, independent unit tests! :{)}

Next, up the view.

View

Contrary to the workflow we just followed in building our product model, normally, we would create the unit tests for a class or method first and then implement the class or method. We didn’t with our model, simply so we could get to some of the nuts and bolts and learn how ku4webApp works. Now that we have an understanding of ku4webApp, we will correct our development flow and start implementing our unit tests first. Now knowing what we will receive from the model this should be pretty straight forward. So, without further ado, let’s give it a shot!

Let’s say that our product view will take the results given to it by the model and display those results as an HTML list of products.

First, we create our products view test.

Image

You will notice one small difference from the outset. There is no mediator. This is because there is no need for one. By the time our view method is called, the notification will have happened, and, as we said, the unit tests should test one unit of functionality. In this case, just the view, not the model. Other than this, though, all things are equal.

Next, we wire the test to our gui.htm.

Image

And then run it.

Image

As expected, it fails. This is because there is no product view yet. So, let go create it.

ku4webApp_101_img21

Now re-run our test.

Image

Perfect!

You have just implemented code following an expected ku4webApp workflow:

  1. Define the feature.
  2. Write the tests.
  3. Implement the feature.

D-W-I: Develop With Intent!

Okay, our create (a.k.a. “new”) test passes. Let’s implement the productsListed method (DWI).

What we are going to say is that we expect the view to update the browser window with an HTML list of the products that we found.

The unit test:

Image

This unit test is doing a few things that aren’t implemented yet. This is certainly the correct way to go about things, but can, certainly, be confusing for those who are unfamiliar with a test driven development mentality. So, lets discuss them here.

Image

First, we created the test skeleton. Next, we created the expected model input, followed by the expected outcome. Then, we made our call and ran our assertions. The only final step is to implement the actual method in the class. So, here it goes.

Image

This implementation is pretty straight forward. We simply implement a view class so that our unit test will pass. As you can see, the structure for a view is exactly the same as for a model. The only differences are that we are implementing a “view” and now the subscriptions are subscribing to the model instead of the services. We are also leveraging a couple of ku4js-kernel classes: $.list, $.str, and $.money. Done. — Let’s run our test!

Image

Great! Things have come together quite nicely. We are successfully implementing a unit tested, MVC, JavaScript front-end web application, and have a defined workflow and supporting ku4webApp system to do so! :{)}

There is one more thing that we can leverage to clean up and consolidate the view a bit before we move on to controllers. ku4webApps have a place to maintain our templates outside of our views. Let’s leverage them to clean up our code.

Templates

Though you can create any kind of template that you like and access it from the view. ku4webApps ship with and contain syntactic sugar for view templates. To leverage a view template simply put your template in the config.templates.views.js file, then leverage the configs with your template classes and access your templates from your view. By doing this you separate configurable templates from the logic of constructing the views — SoC baby! Let’s try this now.

Templates can be used a plethora of different ways. They can be extremely granular and call one another, or they can be very monolithic, or they can be any gradient in between, the choice is yours. The only requirement in a template is a valid template config(s) and construction logic.

What usually make the most sense here, is to start with the config. In our case it is really just a case of cut and copy from our existing products view.

Image

Next, we implement our template. The template will always take some data from a view, then, using the various configs at its disposal, it will choreograph building the expected output. Then, finally, return that output back to the view, for the view to place into the DOM in the proper place.

Image

Templates can access the proper config using the this.$config([“configName”]) method. But ku4webApp also exposes a shortcut for two very common configs: view and forms. You can access those, as we do here, using the this.$form(“[templateKey]”) and this.$view(“[templateKey]”) method respectively. Templates also have various render methods at their disposal. That does not mean that you cannot leverage $.str.render() and any other custom functions that you want to here, but ku4webApp does expose some common rendering utilities to templates, such as: render, renderList, and renderListWithAction, all of which are documented in the README and in the ku4webApp project on Github.

The last step for us, is to remove all unnecessary code from the view and delegate the rendering operation to the template.

Image

As we can see, now all that our view has to do is call for a template, pass data to it, and insert the result on the page. Simple! Let’s compile and re-run our test to make sure that everything still passes!

Image

Perfect! Let’s create a controller that our web page can call and then wire this application!

Controllers

The controllers in a ku4webApp always end up being crazy simple. Their only real tasks are to represent an interface for the client to call, call read() on forms, and marshal data to the models as necessary. We will see more on these features later, but, for now, all we have is a listProducts method. So, we will want to expose this feature to the client so that they can wire it up to, say, a button.

First we will create our unit test. This test will be quite small, because we have no forms to read so and the model interface that we will be calling does not include parameters. Therefore, the controller call to the model will not passing any arguments and the corresponding unit test will only check if we can instantiate the controller and make sure that there are no unnecessary arguments being passed to the model.

bundle.onModelCall

To isolate the controller from the model and still allow the unit test to check the values passed without having to go through the mediator, the bundle offers another unit test specific method to intercept the controller’s call to the model so that we can inspect the data that it passes. This method is bundle.onModelCall. This method takes a function that will receive the data that are to the model when the controller calls it. The obvious method to pass to bundle.onModelCall is an assertion method that contains all the asserters for the test. Much like the assertion method that we used to subscribe to the service callbacks with bundle.callback earlier in this article.

With that said, let’s write our unit test for our controller.

ku4webApp_101_img31

Here we have simply done what we are so familiar with by now, and created a test for creation and one for the method that we intend to implement, listProducts(). One item to note is that the controller unit tests have no need for a mediator so we do not create a var mediator and hold reference to bundle.mediator(). Another difference from model and view unit tests, is one that we have already described. In the controller unit tests we leverage bundle.onModelCall to intercept the model call that will happen inside of our controller’s listProducts method and test that the data passed to the model call is, in fact, null.

Next, let’s wire the test to our gui.

ku4webApp_101_img35

 

And, run the test to see that it fails.

ku4webApp_101_img32

Then, implement the controller.

ku4webApp_101_img33

Here we can see that, just as with the model and view classes before this, we have simply copy and pasted the contents of the README file into our class file and updated the skeleton and implemented methods appropriately.

Now, lets build, and run our unit tests.

ku4webApp_101_img34

BOOM! All green!

Now, we have a unit tested, JavaScript MVC, front-end, eCommerce application that can list products!

Well, alright, alright, alright! We have covered a lot so far in this post! We have created a project structure, implemented a unit tested model, a unit tested view that leverages client-side html templates, and a unit tested controller. We have covered so much, in fact, that I think I will split this tutorial into a few parts. In the next part(s) we will continue with this example and implement our Promotions, Payments, and Logistics; we will implement a simple UI; and take a look at a few gotchas.

Until next time!

I hope that you found this post helpful and interesting, and that you find ku4webApp to be as awesome and useful as I do! It has been nice for me to have unit testing so seamlessly engrained into the development process, and have a common interface and development workflow that makes coding a breeze. It has really made life easy and development fast! 

Please, comment on and share this post with others if you enjoy it; follow @kodmunki on Twitter for regular updates on new developments, deployments, articles, and tools; check out kodmunki™ on Github for cool, managed, and tested kodmunki™ projects, and find heavy tunes to flip bits to on komdunki™ SoundCloud page.
Thank you for reading, and as always, happy coding :{)}
Advertisements

Software development leaders at the forefront of the latest in technology. Whether implementing updates or integrating with existing technology; developing products that push the bleeding edge of the latest in tech; or developing open-source products, paving the way of future tech, kodmunki™ inspires innovation, elevates quality, and drives value to production. kodmunki™ are experts in web, mobile, and hybrid solutions development; local and distributed team management and collaboration; and fast, quality, successful product delivery, offering R&D, training, consulting, and development services. Contact us at info@kodmunki.com. Let's discuss your vision.

Posted in JavaScript, ku4js-webApp, ku4webApp
One comment on “JavaScript MVC with ku4webApp
  1. […] were introduced in: JavaScript MVC with ku4webApp. This wildly awesome framework includes an incredible number of features including services, forms, […]

Enjoy the read? -- Let us know.

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

kodmunki™ Tweets

Enter your email address and receive notifications of new kodmunki™ posts by email.

%d bloggers like this: