Beware of the Bad Javascript for loop

I should have written this blog post on halloween, wooooooo but I hadn’t seen the bug then so that would involve time travel and I haven’t got time for that.  Wait if I invented a method of time travel I would have all the time I would need.  Oh no another bad loop I have got myself in.

Yesterday I blogged about an error I had with a for loop, you can read it below

CRM 2011/2013 – What does setSubmitMode do? and how does it work?

 

This was the code that caused the problem

var attributes = Xrm.Page.data.entity.attributes.get();

for (var i in attributes) {
{ attributes[i].setSubmitMode(never); }
}

 

The problem was when looping round the variables in attributes it was also returning functions, which caused a crash.

I fixed the code by doing this

for (var i in attributes) {

{
i f (isNa!N(i)) {
attributes [i]setSubmitMod.e(“never”);
}
}
}

 

 

Not Quite Right

Something was bugging me about the code.  If that problem was a problem whcommon y had I never seen that code before?

Why had I never seen this error before?

I mentioned the problem and solution to another developer and he instantly said

 

The code must have been using the bad for loop

What!, no one told me there was a bad for loop in Javascript, why has no one told me about the bad for loop, come on people.

 

The Good, the bad and the ugly of For statements

 

The Bad – For In Loop for Array Iteration

I searched the internet and found this forum discussion with a great explanation

http://stackoverflow.com/questions/5263847/javascript-loops-for-in-vs-for

I am copying the top answer because it’s awesome

 

Don’t use for..in for Array iteration.

It’s important to understand that Javascript Array’s square bracket syntax ([]) for accessing indicies is actually inherited from the Object

obj.prop === obj['prop']  // true

The for..in structure does not work like a more traditional for..each/in that would be found in other languages (php, python, etc…).

Javascript’s for..in is designed to iterate over the properties of an object. Producing the key of each property. Using this key combined with the Object‘s bracket syntax, you can easily access the values you are after.

var obj = {
    foo: "bar",
    fizz: "buzz",
    moo: "muck"};


for ( var prop in obj)  {
    console.log(prop);      // foo / fizz / moo
    console.log(obj[prop]); // bar / buzz / muck}

And because the Array is simply an Object with sequential numeric property names (indexes) the for..in works in a similar way, producing the numeric indicies just as it produces the property names above.

An important characteristic of the for..in structure is that it continues to search for enumerable properties up the prototype chain. It will also iterate inherited enumerable properties. It is up to you to verify that the current property exists directly on the local object and not the prototype it is attached to with hasOwnProperty()

for ( var prop in obj)  {
    if ( obj.hasOwnProperty(prop) ) {
        // prop is actually obj's property (not inherited)
    }
}

(More on Prototypal Inheritance)

The problem with using the for..in structure on the Array type is that there is no garauntee as to what order the properties are produced… and generally speaking that is a farily important feature in processing an array.

Another problem is that it usually slower than a standard for implementation.

Bottom Line

Using a for...in to iterate arrays is like using the butt of a screw driver to drive a nail… why wouldn’t you just use a hammer (for)?

 

Hosk Interpretation

The important point here is ForIn statements in javascript return user defined properties as well as numeric indexes.  EEK this explains why I was getting “IndexOf” in my for loop.

It also suggests the index numbers are not gauranteed to come out in a sequential order.  This might not be a problem because all the numbers will come out but if you were expecting them in order the for…in could sneak in a very odd bug to find.

Performance is also slow using the forin loop (although in this case it wasn’t really a problem/consideration), this forum discussion also discusses more about performance of for loops if you are interested in finding out more

http://stackoverflow.com/questions/13645890/javascript-for-in-vs-for-loop-performance

 

The Good

So what For loop should you use in your Javascript for iterating arrays.

When I stepped through this for statement the “IndexOf” value wasn’t returned

var attributes = Xrm. Page. data. entity. attributes. get ();

for ( var i = 0; i < attributes. length; i++) {

attributes[i]. setSubmitMode("never"); }


The Bad

The bad was the original bug someone put in there, it’s the wrong, evil for loop, didn’t the developer know anything!  Well technically I didn’t know about the bad for loop until today.

for (var i in attributes) {
{ attributes[i].setSubmitMode(never);}} 


 

 

The Ugly

The ugly was my original fix

for (var i in attributes) {
    if(!isNaN(i)) {
    attributes [i]setSubmitMod.e(never);}}
    


 

It worked but it wasn’t quite right, it was working around the problem of using the wrong for loop.  It took longer because it was returning functions as well as numbers.

 

what have I learnt

I have learnt there are good and bad for loops in Javascript, yes, I went back and changed the code to use the correct for loop.

I  learned it’s good to discuss things with your fellow developers because you might teach them something new or they might teach you a new trick or way to do something.

 

It’s good to talk

It’s good to talk/blog about quirks and problems you experience programming.  Often developers build up areas of expertease which is usually based around the experience they have gained from projects they have worked on.

 

Be willing to learn

I believe in continuous improvement, always striving to learn and improve.  Every mistake/bad coding practice you can get rid off will be replaced by good code.

More good code == better developer

 

Don’t base your knowledge just on experience

Good developers learn the best practices through their own ideas/experience, reading articles/books on programming.

Good developers are always trying new technology/releases, not only does this get them ready for the new functionality but it gives them ideas

On a related subject is my blog on why you should read the what’s new for CRM 2015, it’s all about learning baby!

CRM 2015 SDK – Why you should read the What’s new for developers

 

I believe CRM certifications (customization and extending) are good ways to learn the new functionality in CRM 2013 and broaden your CRM development knowledge.  I  read and used parts of CRM I hadn’t used in any projects I had worked on but which came up in future projects.

My point is you can learn areas of coding/CRM you haven’t used in a project by reading and trying the functionality yourself.  When the time comes to use it in a project you already have a good idea (and maybe a bit of experience) of how to use it, which means your learning curve on new functionality will be shorter than someone with no knowledge of it.

With CRM 2013 it’s easy, you can easily create a CRM 2013 on line trial to try out all the new functionality, you have no excuse because I have created a blog on how to get a CRM 2013 up and running

Step by Step guide to creating a CRM 2013 Online trial

 

Times change but standards must remain

and if the Hosk catches you writing poor code, I will send round the heavy mob

Advertisement