Showing posts with label Javascript. Show all posts
Showing posts with label Javascript. Show all posts

Monday, December 23, 2013

Remove duplicates in an array in Javascript

If you follow this approach, you need to create another array and if you have performance limitations you need to consider that.

This algorithm will be o(n)complexity in which n is the length.

With jQuery:

 var newArray = []; 
 var array=["amir", "amir", "rahnama", 1, 1]; 
 var newArray = [];

 $.each(array, function(i, element) { 
   if ($.inArray(element, newArray) === -1) {
       newArray.push(region); 
   }
 });

 console.log(newArray); // ["amir", "rahnama", 1];

Vanila Javascript:

 var newArray = []; 
 var array=["amir", "amir", "rahnama", 1, 1]; 
 var newArray = [];

 array.forEach(function(i, element) { 
   if (newArray.indexOf(element) === -1) { 
      newArray.push(region); 
   }
 });
 console.log(newArray); // ["amir", "rahnama", 1];

Friday, November 1, 2013

Merge two object literals into one another in Javascript

I faced this issue a while back that I wanted to achieve something like
var a,b,c;
a = b + c;
for object literals in Javascript. Moreover to that, I wanted to have an option to extend (merge, add or whatever you might want to call it) in a loop, something like the following for the string type:
var result = "",
    j = 0,
    array = ["Amir", "Rahnama"];

    for (; j< array.length;j++) {
       result += array[j] + " ";

}

console.log(result); //Amir Rahnama
I first tried to write my own code and then suddenly found a better solution: jQuery's extend method. In short, jQuery's extend method extends N objects into a target object:

jQuery.extend( target [, object1 ] [, objectN ] )

The target is an object that will receive the new properties, Object1 is an object containing additional properties to merge in and finally, objectN is the additional objects containing properties to merge in. One way of using the function is like following:
var personObject = {person: {name: "Amir", familyName: "Rahnama"}};
var workObject = { work: {workplace: "Stockholm", companyName: "Gapminder"}};
var personWorkObject = {};
    
personWorkObject = $.extend(personObject,workObject);
You could also use the method to extend an object recursively, within a loop for example and that is why I highly recommend you to use this method. If you want to extend the objects recursively, make target the return value of the method, like the code below:
personWorkObject = $.extend(personWorkObject, personObject,workObject);

How to Check if one array is a subset of another array in Javascript?

I encountered this question in my code today. Although there are a lot of messy ways to do it which it will definitely lead to unmaintainable code, I guess I found the best answer.

Just to remind you, this solution will work if your supported browsers are of ECMA-262 standard. Therefore, for some of you guys out there, this might not work.

The key idea is to use every function in Javascript arrays. According MDN, "Tests whether all elements in the array pass the test implemented by the provided function."

Here is the signature of the method:

array.every(callback[, thisObject])

where callback is a function to test for each element, and thisObject refers to the object that we are testing array against (Remember that in Javascript, arrays are object. Right?)

Here is the snippet:

var arrayOfChildrenNames = ["Amir Rahnama", "Mahshid Rahnama"];
var arrayOfFamilyMemberNames = ["Davood Rahnama", "Maryam Toloo", "Amir Rahnama", "Mahshid Rahnama"];

var isarrayOfNamesSubsetOfFamily = arrayOfChildrenNames.every(function(val) { return arrayOfFamilyMemberNames.indexOf(val) >= 0; }));
console.log(isarrayOfNamesSubsetOfFamily); // true

If you are interested to know more about the function, check out MDN Documentation on Array every method

Wednesday, August 28, 2013

Javascript Namespacing: Object Literal Namespace (OLN) in Javascript

Javascript, unlike many other programming languages does not come with its built-in namespace or class pattern. In many other languages such as Java or C#, the code comes with built-in name-spacing and class patterns. Have a look at C#'s namespace pattern below:
namespace Project
{
    class MyClass
    {

    }
}
You may first ask why do we need a namespace to begin with in a language like Javascript?! As a reply, one can simply say that namespaces avoid the global namespace of your application to become polluted by dividing the global namespace into several manageable chunks of code, calling one another. It is very obvious that if you are writing an application you cannot just continues writing it like this, can you?
var getUserInput = function () {

};

var thenSortIt = function() {

};
If you think you can, you are right! But then you lose track of your functions as it becomes so hard to find your functions in thousands of lines of code and newly added functions. Even if you divide them in separate script files, you still are polluting the global namespace, i.e. as the application starts, you are injecting all the code suddenly inside the browser in one big scope. Do you think that is desirable?! If so, think twice.

The Object Literal Namespace (OLN) pattern, comes with a very easy idea. Wrap your namespace inside a very big object literal:
var myNamespace = {
 instanceVariable: undefined,

 setter: function (element) {
  this.instanceVariable = element; 
 },

 getter: function() {
  return this.instanceVariable;
 },

 randomFunctions: function (message) {
  return "Hello, " + message;
 } 
};
In the following script, that is how you call and interact with you OLN in Javascript:
myNamespace.setter(1000); 

console.log(myNamespace.getter()); //Output: 1000

console.log(myNamespace.randomFunctions("Amir Rahnama!")); //Output: Hello, Amir Rahnama!
One fact to remember here, is that by using OLN as your namespace pattern, there is no level of information hiding in your namespace. You are exposing your whole namespace to the caller's code. Meaning that, you can replace the second line of above with the following line, keeping the output still the same:
console.log(myNamespace.instanceVariable); //Output: 1000
Actually, that is one of the main reasons that many developer dislike OLN namespaces, because they believe in a namespace with public and private values at the same time.

One last thing to note is that you can dynamically extend your OLN Namespace by the following code:
//Dynamically add instance variables to myNamespace
myNamespace.newInstanceVariable = "I am new";

//Dynamically add newFunction to myNamespace
myNamespace.newFunction = function (newMessage) {
 return "Hello Again," + newMessage;
};

And you can guess that you can use them as soon as they are declared:

console.log(myNamespace.newInstanceVariable); //Output: I am new
console.log(myNamespace.newRandomFunction("Mr, Amir Rahnama!")); //Output: Hello Again, Mr. Amir Rahnama!

Sunday, July 14, 2013

Listen/Watch for object or array changes in Javascript with Watch.JS

I was assigned to project in which it was desired to migrate from a Backbone project to plain jQuery/Javascript project. As you may know, Backbone is a Javascript framework which embodies your application in a MVC platform. The nice thing about a backbone model is that it is an object literal with an array of attributes which you get either with model.attributes or model.get("attribute's name"):
var AppModel = Backbone.Model.extend({

    // Model instance members go here ...

    defaults: {
        //Default model attributes
    },

    initialize: function() {
        // This line will watch for changes in model object and will call the callback
        // i.e. The killer famous line!
        this.listenTo(this, "change", callback);
    }
});

Whenever the model in your backbone application changes you can handle the "change" event in a pretty neat way like this:

object.listenTo(other, event, callback)

As you see the model.listenTo has three arguments: First is the model object, second is the type of event to be captured and finally the callback function which will be fired in case that event will happen. 

So the idea here is to implement the same model.listenTo "change" method on the object literal or the model. I started looking at different stackoverflow discussions and finally made my decision. The solution (well, at least one of best ones to be fair) exists in a well-written library called Watch.JS. The weird thing about this case is that browser have different approaches regarding this. For example there is a sweat property on the Object prototype called Watch. I guess the idea behind Watch.JS is actually coming from there. 

The steps needs to be taken are quite simple. First, add the source of Watch.js, Second create an object literal and third, enable watch for the object/array and attach a callback function to it, like the following chunk of code:
 
   var defaultModelAttributes = {
      personName: "Amir Rahnama"
   };

   //defining a 'watcher' for an attribute of your object literal / array
   watch(defaultModelAttributes, "personName", function() {
     alert("personName value changed!");
   });

   //when changing the attribute its watcher will be invoked
   defaultModelAttributes.personName = "A stupid guy";

You can also look for all changes in the same object literal by changing line 11 with the followings:
watch(defaultModelAttributes, function() { ... });

You can also set how deep you would like your changes to be watched, just pass in a depth token to the watch function after you declare the callback function, as in the following:

var defaultModelAttributes = {
    person: {
        personId: "870718-5768",
        personName: {
            firstName: "Amir",
            lastName: "Rahnama"
        }           
    }
    };

    watch(defaultModelAttributes, function(){
        alert("defaultModelAttributes is changed");
    }, 2);

    defaultModelAttributes.person.personName.lastName = "Akhavan";

UPDATE: I tried to use the library with RequireJS, but I believe that there should be a compatibility issues, there. I do not know the reason yet, but in case you are interested here is the link to issue on WatchJS Github page: Setting an object literal attribute with RequireJS does not trigger the passed callback function.

Friday, July 12, 2013

var that=this in Javascript

If you have ever saw or read any open-source library in Javascript, I can assure you at least in one part of the code, you will see something like following:
var that = this;
You may wonder why is that so? Well, in short answer it is because of how Javascipt defined its scope. In many modern programming languages the type of scope is a block scope. In block scope, everything which is wrapped inside a curly brace will not be visible outside of the braces. In Javascript, it is functions scope. What does that mean? It means that a scope unit in defined within function, and all variables which are defined within the function are not accessible outside of that function. In Javascript it is very common that you define a function inside a function, whether that is a function of an object literal, or closures. Actually the case with our case mainly happens within such case.

Ok, So let us consider a very common case in Javascript programming. Let us say that you have created an object literal:

var person = {
 id : 1
}; 

Now let us say that you need to augment that object literal. Here, we are trying to do this:

person.augmentInfo = function () {
   var setNewId = function () {
    
   // this here does not refer to the person context, but rather to setNewId function
   // therefore the following line cannot set the new Id 
           
   this.id = 3;
 }

 setNewId();
};

Now if you check whether new id has been set or not, you see that it has not! Check the following lines yourself:
myObject.augmentInfo();
console.log(myObject.id); //undefined is logged

So basically the reason why we use that notation is when going inside a new scope zone, you can save the value of this in the outter scope to be able to access variables and methods in the outter context from the inside context.


person.augmentInfo = function ()
{
        var that = this;
        
        var setNewId = function () {
    
            // this here does not refer to the person context, but rather to setNewId function
            // therefore the following line cannot set the new Id 
           
            that.id = 3;
        }

        setNewId();
};

Now if you verify it, you can see that right now, the newId is being set corrently.

myObject.augmentInfo();
console.log(myObject.id); //3 is logged, correctly

Monday, July 8, 2013

Load jQuery UI with requireJS

RequireJS is one popular script loading framework out on the web. At the same time, most of the web applications and websites are now using jQuery and there are quiet a lot of them that use jQuery UI as well. You may know that jQuery UI is dependent on jQuery, meaning that in order for jQuery UI to load correctly, jQuery should be loaded first.

In older version of RequireJS, it was a lot more harder (and ugglier you may say) to include jQuery UI since the jQuery UI library (unlike jQuery) is not following an  Asynchronous Module Definition  (AMD) style. Then you need to include AMD-enabled scripts which were built within communities and especially James Burke. However, in the last versions of RequireJS, a lot of features were added regarding this.

Remark: If you are not familiar with Asynchronous Module Definition (AMD) and interested to know more, read this article Why AMD?

So let's get on with it. I presume that you are following a folder structure like this:




Here is how you minimal index.html file should look like:


    sample_app
    




One of the scripts that handles a lot of key information is the one attributed with data-main (i.e. main which stands for main.js). In this script you can define your library paths and a tag called shim which handles dependencies and non-AMD module loading. After that there is the code on how application will continue its initialisation process. This looks something like:


require.config({
    paths: {
        "jQuery": "../libs/jQuery//jquery-1.9.1",
        "jQueryUI": "../libs/jQueryUI/jquery-ui-1.10.3.custom"
    },
    shim: {
        "jQueryUI": {
            export:"$" ,
            deps: ['jQuery']
        }
    }
});

require(["app"], function(App)
{
    App.initialize();
});

As you can see with the paths you are declaring a key-value pair of library conventions and paths and with shim, you are flagging the non-AMD modules which in this case is also dependes on jQuery. In the last step, add the following to your app.js file:

define(["jQuery", "jQueryUI", "guiFunctions"], function ()
{
   var initialize = function ()
   {
      //jQuery, jQuery UI are added here now ...
   };
  
   return {
      initialize : initialize
   };
});
And that is it!

Monday, July 1, 2013

How to migrate from live() method in jQuery 1.9?

As jQuery documentation says it here, the famous live() method has been completely removed in jQuery 1.9, so you have to migrate from it, anyhow.

It is actually quiet simple. The jQuery Library has introduced a method called on() which is even more complete in what live() method was doing. The following is its signature:

.on( events [, selector ] [, data ], handler(eventObject) )

where events is of type String  and it is one or more space-separated event types and optional namespaces, such as "click" or "change", selector is also of type String and it is the selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element. Data can be of any type and it is passed to the handler in event.data when an event is triggered, and lastly, handler is of type Function (to execute when the event is triggered).

There exist a rough formula to change your methods from live() to use on(), instead. Have a look at my example:
// This is the old live() method
$("#element-id").live('change', function(){ 
  // Event handler code goes here ...
});

//This is its equivalent in jQuery 1.9
$(document).on('change', "#element-id", function(){
  // Event handler code goes here ...
});
Were you able to find the formula? It is quiet easy: Change the place of first argument of live method to the third one in on(). Add the root DOM element to the first parameter of on() method and keep the event type. That's it!

Wednesday, June 19, 2013

Implement Java Map in Javascript

//Map is an Object Literal 
var map = {};

//Key Needs To be a String
var key = "";

// Value can be any String, Number or an Object itself
var value;

//------- Method I --------------

// Assign a value to a key 
map[key] = value;

// Return value by a key 
var returnedValue = map[key];

//-------- Method II ----------

// Return value by a key
var returnedValue = map.key;

// Assign a value to a key
map.key = value;

Tuesday, June 18, 2013

Load JSON Files Synchronously with jQuery

In jQuery, the getJSON operator can load any JSON file, however this operation is done asynchronously. Meaning that, in cases where you need to wait until your data file is loaded, using getJSON method is useless. Here is one way you can achieve your goal of loading JSON files synchronously:

function loadJsonFileSynch()
{
        $.ajax({
            url: 'path/to/json/file.json',
            async: false,
            dataType: 'json',
            success: function (response) {
                $.each(response, function(key, val) {
                    // Do processing here
                });
            }
        });
}

Thursday, May 16, 2013

Match an element against an array in Javascript

There are times when you need to check whether an element is inside an array. You might want to loop thorough the whole array and check one-by-one whether the element belongs to an array or not:
var element = "one";
var array = ["one", "two", "three"];

for (var i= 0; i < array.length; i++)
{
   if (element === array[i])
   {
      alert("element exists in array");
   }
}
This approach is not optimized. First, it will produce additional lines of unnecessary code and therefore makes the code look ugly. Second, looping through element of an array is costly, especially when the array has two many elements. A more optimized way of handling this case is with use of Regular Expressions. Without further a due, let us look at the code:
if ((new RegExp('\\b' + array.join('\\b|\\b') + '\\b') ).test(element))
{
   alert("element exists in array");
}
In this approach, we create a new regular expression by joining elements of array into an string and match it against the element with test() method. Just to remark, \b matches the empty string at the beginning or end of a word.

Wednesday, January 16, 2013

Add rows to HTML table using jQuery





Add Title Here


 
First HeaderSecond Header
Add Row
Find it in JSFiddle: Add rows to HTML table using jQuery