Showing posts with label Architecture. Show all posts
Showing posts with label Architecture. Show all posts

Sunday, May 1, 2016

Components in angular 1.5.x

In my previous article I described my view on a component based architecture. In this post I want to focus on how I applied this in a real life application with angular. Since the 1.5 version was released, components have become first class citizens just like in Angular 2, Ember 2, React,… On the other hand components aren’t so revolutionary. We have already known them for a long time as directives, but we never used them like this. Generally, we would only use directives for manipulating the DOM directly or in some cases to build reusable parts.
The components in angular 1.5 are a special kind of directive with a bit more restrictions and a simpler configuration. The main differences between directives and components are:
  • Components are restricted to elements. You can’t write a component as an attribute.
  • Components always have an isolated scope. This enforces a clearer dataflow. No longer will we have code that will change data on shared scopes.
  • No more link functions, but only a well-defined API on the controller.
  • A component is defined by an object and no longer by a function call.

Well-defined Lifecycle

Components have a well-defined lifecycle:
  • $onInit: This callback is called on each controller after all controllers for the element are constructed and their bindings initialized. In this callback you are also sure that all the controllers you require on are initialized and can be used. (since angular 1.5.0)
  • $onChanges: This callback is called each time the one-way bindings are updated.  The callback provides an object containing the changed bindings with their current- and previous value. Initially this callback is called before the $onInit with the original values of the bindings at initialization time. This is why this is the ideal place for cloning your objects passed through the bindings to ensure modifications will only affect the inner state.
    Please be aware that the changes callback on the one-way bindings for objects will only be triggered if the object reference changes. If a property inside the object changes, the changes callback won’t be called. This avoids adding a watch to monitor the changes made on the parent scope (works correctly since angular 1.5.5)
  • $postLink: This is called once all child elements are linked. This is similar to the (post) link function inside directives. Setting up DOM handlers or direct DOM manipulation can be done here. (since angular 1.5.3)
  • $onDestroy: This is the equivalent of the $destroy event emitted by the scope of a directive/controller. The ideal place to clean up external references and avoid memory leaks. (since angular 1.5.3)

Well-defined structure

Components also have a clean structure. They exist out of 3 parts:
  • A view, this can be a template or an external file.
  • A controller which describes the behaviour of the component.
  • Bindings, the in- and outputs of the component. The inputs will receive the data from a parent component and by using callbacks, will inform the parent component of any changes made to the component.

Bindings

Because components should only be allowed to modify their internal state and should never modify any data directly outside its component and scope. We should no longer make use of the commonly used two-way binding (bindings: { twoWay: “=” } ). Instead since angular 1.5 we now have a one-way binding for expressions (bindings: { oneWay: “<” } ).
The main difference with the two-way binding is the fact that the bound properties won’t be watched inside the component. So if you assign a new value to the property, it won’t affect the object on the parent. But be careful, this doesn’t apply on the fields of the property, that is why you always should clone the objects passed through the bindings if you want to change them. A good way to do this is working with named bindings, this way you can reuse the name of the bound property inside the component without affecting the object in the parent scope.
   1: module.component("component",{
   2:     template: "<div>{{$ctrl.item}}</div>"
   3:     bindings: {
   4:         inputItem: "<item"
   5:     }
   6:     controller: function(){
   7:         var $ctrl = this;
   8:         this.$onChanges = function(changeObj){
   9:             if(changeObj.inputItem){
  10:                 this.item = 
  11:                     angular.clone(changeObj.inputItem.currentValue);
  12:             }
  13:         }
  14:     }
  15: });
Another way to pass data is by using the “@” binding. This can be used if the value you are passing is a string value. The last way is using a “&” binding or a callback to retrieve data through a function call on the parent. This can be useful if you want to provide an auto complete component with search results data.
For exposing the changes inside the component we can only make use of the “&” binding. Calling a callback in the parent scope is the only way that we can and should pass data to the parent scope/component.
Let’s rephrase a little:
  • “=” binding (two-way) should no longer be used to avoid unwanted changes on the parent’s scope.
  • “<” binding (one-way) should be used to retrieve data from the parent scope passed as an expression.
  • “@” binding (string) should be used to retrieve string values from the parent scope.
  • “&” binding (callback) can be used to either retrieve data from the parent scope or be used as the only way to pass data to the parent scope.

Summary

The components way of working in angular 1.5 closes the gap for migrating your code to an angular 2 application a bit more. By building your apps in the angular 2 style you are already thinking on the same level. This will ease the migration path by shifting away from the controller way of working.
Directives will still have an existence beside the components. You will still have some cases where you will want to use attributes instead of elements or have the need of a shared scope for the UI state. But in most cases components will do the trick.

Friday, January 25, 2013

JavaScript: OO programming using the Revealing Prototype Pattern

I’m currently playing around with SPA (Single Page applications), meaning a lot of JavaScript to write. One of the principals in OO programming is don’t repeat your self. That is why I was looking for ways to accomplish this. In languages as C#, Java, VB, … we can make use of classes for this, but in JavaScript we don’t have a keyword class to define classes. (Except if you are using Typescript, this is a language build on top of JavaScript that allows you to define classes like you do in C# or Java. You should really check it out.)

Closures

In JavaScript you only have functions, but all these functions have closures. A closure is a special kind of object that combines two things: a function, and the environment in which that function was created. The environment consists of any local variables that were in-scope at the time that the closure was created. In the example below the “obj” variable is a closure which has “Hello world!” and the function innerFunction in scope when the closure was created.

   1: function closure(){
   2:     var hello = "Hello";
   3:     function innerFunction(suffix){
   4:         alert(hello + " " + suffix);
   5:     }
   6:     return innerFunction;
   7: }
   8:  
   9: var obj = closure(); // Creates a new closure
  10: obj("world!"); // This will show the message box with "Hello world!"

The innerFunction also has his own closure containing the suffix variable. Because the innerFunction is inside of an other scope, it can make use of the parent scope as long as it is created in the parent scope, and there aren’t duplicate names. In the case inner- and outer scope have the same variable or function defined, the value of the inner scope will be the one defined in the inner scope.



   1: function a(){
   2:     var c = "1"
   3:     function b(c){
   4:         alert(c);
   5:     }
   6:     return b;
   7: }
   8:  
   9: var x = a();
  10: x("5"); // The message box will show 5.

Objects


To create a new object in JavaScript, we need to do 2 things. First make a class definition using a function. In the example bellow we define the class in the function “Class”. You see we can have private fields and private methods inside. Because none of this 2 are returned at the end, they will only exist inside the closure and be only accessible inside it. At the end of the class definition we return an object literal. This object literal will contain all the public functions and fields the object has.



   1: function Class(){
   2:     var privateField = "private"
   3:     function privateFunction(){
   4:         return privateField;
   5:     }
   6:  
   7:     return {
   8:         publicField: "public",
   9:         publicFunction: function(){
  10:             return privateFunction();
  11:         }
  12:     }        
  13: }
  14:  
  15: var instance = new Class();
  16: alert(instance.publicField); // shows "public"
  17: alert(instance.publicFunction()); // shows "private"

There is also a second way to expose fields and functions public. You can do this by adding the fields and the functions to the scope of the function. You can access the scope of a function, by using the this keyword.



   1: function Class() {
   2:     var privateField = "private"
   3:     function privateFunction() {
   4:         return privateField;
   5:     }
   6:  
   7:     this.publicField = "public";
   8:     this.publicFunction = function () {
   9:         return privateFunction();
  10:     };
  11: }
  12:  
  13: var instance = new Class();
  14: alert(instance.publicField); // shows "public"
  15: alert(instance.publicFunction()); // shows "private"

Prototype Pattern


In the objects chapter of this post I showed you 2 ways to define a class. The disadvantage of the above code is that everything inside the class definition gets created when you create a new instance of the class. When creating a lot of instances you can imagine that you will get memory issues after a while. That is when the prototype pattern can come to the rescue.


The prototype pattern is a creational design pattern used in software development when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects (Source Wikipedia). This means instead of creating the entire object every time, only the state (which makes the object instances unique) will be created, but all the other stuff like methods will be cloned. By doing this you can save a lot of memory allocation.


In the example below you can see the prototype pattern in action. As mentioned only the state of the object is kept in the object, but every thing that can be shared will be cloned when a new instance is created. This means the publicField we have will always have the value “public” no matter how many instances of the object you created and if you change the value of it, it will be changed for all existing and new instances. This is the same for the publicFunction and the body of the function, but in the function you are able to access the state of the instance. This way you can write the function signature once, but access and change the state of the instance individually.



   1: function Class(p) {
   2:     var privateField = p;
   3:     function privateFunction() {
   4:         return privateField;
   5:     }
   6:  
   7:     this._privateFunction = privateFunction;
   8: }
   9:  
  10: Class.prototype.publicField = "public";
  11: Class.prototype.publicFunction = function () {
  12:     return this._privateFunction();
  13: };
  14:  
  15: var instance = new Class("private");
  16: alert(instance.publicField); // shows "public"
  17: alert(instance.publicFunction()); // shows "private"

With the above example you can also create a second instance with “public” as argument and in this case the publicFunction will return “public”.


One of the disadvantages of this approach is the fact that all the fields you want to access in the shared functions (defined in the prototype), need to be public on the instance. Meaning they need to be returned or added to the scope. To solve this a bit there is a convention that private fields, who need to be accessible in the shared parts have a “_”-prefix. This won’t make them inaccessible, but intellisense will ignore them, so making it a bit harder to know.


Revealing Prototype Pattern


As you see with the prototype pattern every thing you define as shared is public. This is where the revealing prototype goes further. It allows you to have private functions and variables inside the shared scope.



   1: function Class() {
   2:     var privateField = "private"
   3:     function privateFunction() {
   4:         return privateField;
   5:     }
   6:  
   7:     this._privateFunction = privateFunction
   8: }
   9:  
  10: Class.prototype = function () {
  11:     var privateField = "Hello";
  12:     var publicField = "public";
  13:     function privateFunction() {
  14:         return privateField + " " + this._privateFunction();
  15:     };
  16:  
  17:     return {
  18:         publicField: publicField,
  19:         publicFunction: privateFunction
  20:     };
  21: }();
  22:  
  23:  
  24: var instance = new Class();
  25: alert(instance.publicField); // shows "public"
  26: alert(instance.publicFunction()); // shows "Hello private"

Conclusion


By using the revealing prototype pattern you have several advantages:



  • Less memory use, everything defined as shared is only created once.
  • You have the advantage to encapsulate your private code and expose public only the functions and fields you want
  • The classes are open for extension but closed for modification: you can easily add extra functionality without affecting the existing implementation.

Of course there are some down sizes too:



  • The definition of the constructor and the class implementation (for the prototype parts) are separate
  • You can make your state fully private if you need it in the shared parts.

For me the leverage of the advantages are bigger than the disadvantages. I’m using this pattern more and more. I’m also busy migrating my library to use this pattern, so other people can easily extend my library and add there own functionality without changing the source file and the existing implementation.

Friday, September 21, 2012

IndexedDB: MultiEntry explained

For a long time I was not sure what the purpose of the multiEntry attribute was. Since non of the browsers supported it yet, but since sometime Firefox and even the latest builds of Chrome support it, it all came clear to me. The multiEntry attribute enables you to filter on the individual values of an array.For this reason, the multiEntry attribute is only useful when the index is put on a property that contains an array as value.

When the multiEntry attribute is on true, there will be a record added for every value in the array. The key of this record will be the value of the array and the value will be the object keeping the array. Because the values in the array are used as key, means that the values inside the array need to be valid keys. This means they can only be of the following types:

  • Array
  • DOMString
  • float
  • Date

So far for the theory, an example will make everything clear.

In the example below I will use an object Blog. A blog contains out of the following properties:

   1: var blog = { Id: 1
   2:            , Title: "Blog post"
   3:            , content: "content"
   4:            , tags: ["html5", "indexeddb", "linq2indexeddb"]};


In the indexeddb we have an object store called blog which has an index on the tags property. The index has the multiEntry attribute turned on. If we would insert the object above, we would see the following records in the index:















keyvalue
“"html5”{ Id:1, Title: “Blogpost”, content:”content”, tags: [“html5”, “indexeddb”, “linq2indexeddb”]}
“indexeddb”{ Id:1, Title: “Blogpost”, content:”content”, tags: [“html5”, “indexeddb”, “linq2indexeddb”]}
“linq2indexeddb”{ Id:1, Title: “Blogpost”, content:”content”, tags: [“html5”, “indexeddb”, “linq2indexeddb”]}

So for every value in the array of the tags attribute, a record is added in the index. This means when you start filtering, it is possible that the same object can be added to the result multiple times. For example if you would filter on all tags greater then “i”, the result would be 2 times the blog object I use in this example.

Thursday, August 9, 2012

Promises: jQuery deferred object vs WinJS Promise

When I was adjusting my Linq2IndexedDB library to enable Windows 8 development, I had some little issues porting the jQuery promises to WinJS promises. In this post I will show you some differences I had issues with and how I fixed them.

Passing context

The first problem I ran into: WinJS promises doesn’t support passing a context. Because I don’t take advantage of the context yet, this wasn’t an issue for me yet. I easily solved it by writing a wrapper around the 2 promises. In case of the jQuery promise, the context gets passed. And in case of the WinJS promise, I just ignore it for the moment and hope it will get implemented in the future.

   1: function promiseWrapper(promise) {
   2:     if (isMetroApp) {
   3:         return new WinJS.Promise(function(completed, error, progress){
   4:             promise({
   5:                 complete: function (context, args) {
   6:                     completed(args);
   7:                 },
   8:                 error: function (context, args) {
   9:                     error(args);
  10:                 },
  11:                 progress: function (context, args) {
  12:                     progress(args);
  13:                 }
  14:             });
  15:         });
  16:     } else if (typeof ($) === "function" && $.Deferred) {
  17:         return $.Deferred(function (dfd) {
  18:             promise({
  19:                 complete: function (context, args) {
  20:                     dfd.resolveWith(context, [args]);
  21:                 },
  22:                 error: function (context, args) {
  23:                     dfd.rejectWith(context, [args]);
  24:                 },
  25:                 progress: function (context, args) {
  26:                     dfd.notifyWith(context, [args]);
  27:                 }
  28:             });
  29:         }).promise();
  30:     }
  31: }

Passing multiple parameters


A second problem I had was the fact that the WinJS only allows one argument to be passed when calling a complete, error or progress callback. Because I needed to pass multiple values in my library, I needed to rewrite every complete, error and progress method I called. Instead of just passing multiple arguments to the callback methods, I needed to wrap the arguments into an array so they could be passed as single argument.


But that wasn’t enough. Because the jQuery promise is smart enough to convert an array of arguments into a callback with multiple arguments, I needed to wrap the array of arguments into an other array (If you look in the sample above, you will see in case of the jQuery promise, brackets (‘[]’) were added around the args argument.). I needed to do this, because it was the only way to get the same signature when working with the WinJS & jQuery promise.



   1: promiseWrapper(function (pw) {
   2:     pw.complete(context, [arg1, arg2]);
   3: });

Progress Event Doesn’t fire in Winjs promise


The last issue I suffered was the fact that a progress event in didn’t fire in some cases. After a little investigation, I came to the conclusion that I was calling the progress event, before the promise object got created. I first noticed this when I was creating a transaction on the IndexedDB API. When a transaction was created, I fired a progress event with the transaction data. In other methods, where I needed the transaction, I used this the progress call to execute my queries. Once the transaction was committed, the complete event got fired. Because the progress call never got called, the query was never executed. This way the transaction was immediately committed and the complete callback got called without any action taken.


To fix this I delayed the progress call a little bit. By adding a setTimeout of 1 ms I noticed my problem was solved, and my progress events got called.



   1: if (isMetroApp) {
   2:     setTimeout(function () {
   3:         var txn = db.transaction(objectStoreNames, transactionType); 
   4:         txn.oncomplete = function (e) {
   5:             pw.complete(txn, [txn, e]);
   6:         };   
   7:         pw.progress(txn, [txn]);
   8:     }, 1);
   9: }

Conclusion


As seen above working with the WinJS is a slice different of working with the deferred object in jQuery. But with the given workarounds, it is possible to solve the most issues. I hope that Microsoft will take a look at the jQuery deferred object in the future and add some of the jQuery capabilities (context, multiple arguments) into the WinJS promises. And hopefully the progress bug gets solved, so the ugly setTimeout can disappear in my code.