More fun with Jasmine, Sinon and JavaScript

By Kenneth 'RabidDog' Clark at January 26, 2012 22:48
Filed Under: Code, JavaScript, Test Driven Development

Once again delving into front end JavaScript development (which I might add is not all that fun Sad smile) I have started to gather a few tid bits on good sites to have a look at. Before I post that I want to make a few points on the whole JavaScript world and why I find it to be so annoying to work with.

 

A few general trends I have noticed in the web development world is that the idea of using solid architectural practises is often undermined by the need for fancy front end user experiences. This leads to a very dangerous situation were we sacrifice the integrity of backend services to facilitate fancy front end experiences. This being said, I must admit, that I do like the trend developing in the JavaScript development community to implement test cases. Lets hope this trend continues!

 

The one thing that really, and I mean REALLY, frustrates me around the JavaScript language is the lack of structure. While this might be a plus for some people, it is highly frustrating me. Why has the ECMA specification not allowed for a simple import function? All other major platforms and languages allow you to import reference files. Yes, I know you can merge them, minify them and then wrap them in cheese but why should you have to? I know that this decreases HTTP traffic in certain instances but it is a pain in the rectum to develop for. Some sort of import directive is long over due in JavaScript. Why should my HTML pages contain script reference tags? This doesn’t fit in with the view knowing nothing about the application layer. With unobtrusive JavaScript becoming big this is a serious flaw in the design. I know there are ways to get round all this but all mechanism involving referencing files is contrived.

 

That single word sums up my feelings on JavaScript development, it is contrived. That an the lack of support by any major IDEs is also painful. Yes, you should know how to do this without the help of an IDE but that is like telling a dentist to use a handle drill because an electric drill is too helpful.

 

The lack of standards regarding engineering practises in JavaScript, the custom JavaScript engines found in all major browsers and a few other things still make JavaScript development a “dark art”. I take my hat off to good, productive JavaScript developers, you guys truly have a gift. I am also left wondering who long it will be before JavaScript grows up.

 

Anyways if you looking to get into the whole JavaScript TDD and MVC boat I would highly recommend that you check out a fantastic set of write ups by Jim Newbery over at tinnedfruit.com.

 

http://tinnedfruit.com/2011/03/03/testing-backbone-apps-with-jasmine-sinon.html

 

Well here is to JavaScript growing up!

Google+ C# client

By Kenneth 'RabidDog' Clark at November 10, 2011 23:57
Filed Under: C#, Code, Web

After the hackathon, I noticed that the .NET realm is not covered by the current Google+ clients. This prompted me to write a client to facilitate the current APIs. It is strongly typed, easy to use and pretty handy. I have included basic tests to describe it’s usage. Currently it only supports the API Key. Next is the paging and OAuth 2. Check it out if you get a chance https://github.com/RabidDog/GooglePlusNet

 

Ciao

C# HttpWebRequest and HttpWebResponse

By Kenneth 'RabidDog' Clark at November 09, 2011 13:34
Filed Under: C#, Code, Web

 

Another quick post on doing a simple http request and processing the response. Working on the Google+ client for C# and due to the fact the API is REST based, I need to be able to make an HTTP request and process the HTTP response. When looking at the client I am implementing I decided to wrap the whole round trip into a single operation. Here is the results of my labor.

 

First let me give you the class definition:

 

using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text;

namespace CodeShark.Communication
{
    class HttpProcessing
    {
        public static String ProcessRequest(string requestUrl)
        {
            // This will be the raw string response
            String output;

            var httpWebRequest = (HttpWebRequest)WebRequest.Create(requestUrl);
            httpWebRequest.MaximumAutomaticRedirections = 4;
            httpWebRequest.MaximumResponseHeadersLength = 4;

            httpWebRequest.Credentials = CredentialCache.DefaultCredentials;

            using (var httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse())
            {

                Debug.WriteLine("Content length is {0}", httpWebResponse.ContentLength);
                Debug.WriteLine("Content type is {0}", httpWebResponse.ContentType);

                using (var responseStream = httpWebResponse.GetResponseStream())
                {
                    if(responseStream == null)
                        throw new InvalidDataException("Could not retrieve any data from the URL " + requestUrl);


                    var readStream = new StreamReader(responseStream, Encoding.UTF8);

                    output = readStream.ReadToEnd();

                    Debug.WriteLine("Response stream received.");
                    Debug.WriteLine(output);
                }
            }

            return output;
        }
    }
}
Now for a quick explanation. We create the HTTP request using the URL supplied. Then we set some limits on the bouncing the HTTP request can do and set the credentials. The request is fired off when we call the httpWebRequest.GetResponse(). Once we have the HttpWebResponse we need to read the response stream. We get the response stream by calling httpWebResponse.GetResponseStream(). Using this stream you can read the response (presumably text). Pretty simple, nothing to fancy but something we do quiet often without even knowing it.

Build now, make money later

By Kenneth 'RabidDog' Clark at November 09, 2011 10:31
Filed Under: Code, Work

After reading an interesting piece of market research around the general idea and reasons for building mobile applications, everyone always pointed out the fact that they wanted to make money off their applications, so I thought I would make an observation about it.

 

Firstly, money is needed. We need it to pay the bills, we need it survive, to remain clothed and to have a roof over our heads. There is definitely a very real need for money, I am not denying this. However if we look at successful online software products, very few of them first set out to make money. Their first goal was to attract a user base.

 

At the recent G|South Africa (Google South Africa) days, the key note speaker went a little into the methods that Google uses when building applications. He pointed out that the when presenting an idea, the last thing Google wants to hear is how you going to make money off it. The first thing they tell you to do is to get the users!

 

Why is this important? Well it is pretty simple really. If you don’t have people using your application, you won’t ever make money off it. If people cannot use the application without risk they won’t try it. Especially at the rate that applications are being released and the substandard quality of the product. I am incline to believe that the Apple App store is doing better just by virtue of the fact that people know they have quiet a rigorous quality assurance procedure.

 

So my advice to you is pretty much the same as Google’s. Build the application first. Release it for free, get the user base, then and only then try to figure out how to make money off it.

 

Just another point on the inability to monetize applications in South Africa through the Android Market. South Africa has some of the nastiest monetary policies in the world. Look how long it took us to get PayPal. So it is not because Google is not interested in South Africa, it is just incredible difficult to establish the mechanisms in South Africa.

C# XML and Binary Serialization

By Kenneth 'RabidDog' Clark at November 08, 2011 17:55
Filed Under: C#, Code, Architecture

Recently was working on a small project that required me to store a collection of objects. So I figured I would refresh my knowledge of the serialization available in C#.

 

First I had a look at the XmlSerializer. First you need to define an object to serialize.

 

[Serializable, XmlRoot(Namespace = "http://rabiddog.co.za")]
public class Dog
{
    public Dog(String name, int age)
    {
        this.Name = name;
        this.Age = age;
    }

    public string Name { get; set; }
    public int Age { get; set; }

    //The XmlSerializer requires a default Constructor
    public Dog() { }
}

 

Now that we have the class defined, lets create a collection and serialize that collection to an XML file. Create a console application and then add the following method

 

private static void XmlSerialize()
{
    Dog dog1 = new Dog("Charlie", 42);
    Dog dog2 = new Dog("Jim", 32);


    List<Dog> myDogs = new List<Dog>{dog1, dog2};

    using (Stream stream = new FileStream("MyDogs.xml", FileMode.Create, FileAccess.Write, FileShare.None))
    {
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Dog>), new Type[]{typeof(Dog)});
        xmlSerializer.Serialize(stream, myDogs);
    }
}

 

Then call the method from the Main() function, let it run and you should end up with a file called MyDogs.xml in the debug/bin directory. The file should look something like this

<?xml version="1.0"?>
<ArrayOfDog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Dog>
    <Name xmlns="http://rabiddog.co.za">Charlie</Name>
    <Age xmlns="http://rabiddog.co.za">42</Age>
  </Dog>
  <Dog>
    <Name xmlns="http://rabiddog.co.za">Jim</Name>
    <Age xmlns="http://rabiddog.co.za">32</Age>
  </Dog>
</ArrayOfDog>
 

Well that was pretty simple. All we had to do was add the [Serializable] annotation to the class and then create an instance of XmlSerializer to write it to. You could also set the properties to be attributes by decorating them with the [XmlAttribute] annotation.

 

Cool, lets move onto the binary serialization shall we? Using the same Dog class we are going to serialize this down to a binary file.

 

We do that by changing the serializer we are using to the BinaryFormatter:

private static void BinarySerialize()
{
    Dog dog1 = new Dog("Charlie", 42);
    Dog dog2 = new Dog("Jim", 32);


    List<Dog> myDogs = new List<Dog> { dog1, dog2 };

    BinaryFormatter formatter = new BinaryFormatter();

    using (Stream stream = new FileStream("MyDogs.dat", FileMode.Create, FileAccess.Write, FileShare.None))
    {
        
        formatter.Serialize(stream, myDogs);
    }
}

 

Don’t forget to call this method from the Main method. This should produce a MyDogs.dat file in the debug/bin directory. Happy days but there is just one problem. What good is it serializing it if we can deserialize it?

 

First lets deserialize our XML like so

private static void XmlDeserialize()
{

    using (Stream stream = new FileStream("MyDogs.xml", FileMode.Open, FileAccess.Read))
    {
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Dog>), new Type[] { typeof(Dog) });
        List<Dog> myDogs = (List<Dog>)xmlSerializer.Deserialize(stream);

        foreach(Dog dog in myDogs)
        {
            Console.WriteLine("My Dog {0} is {1} years old", dog.Name, dog.Age);
        }
    }
}

 

And the method to deserialize our binary file would be something along the lines of

private static void BinaryDeserialize()
{
    BinaryFormatter formatter = new BinaryFormatter();
    using (Stream stream = new FileStream("MyDogs.dat", FileMode.Open, FileAccess.Read))
    {
        List<Dog> myDogs = (List<Dog>)formatter.Deserialize(stream);

        foreach (Dog dog in myDogs)
        {
            Console.WriteLine("My Dog {0} is {1} years old", dog.Name, dog.Age);
        }
    }
}

 

It thought this was a particularly neat way of storing data on application close. Serialize your object graphs and exit. When you start the application deserialize back to the original state and off you go. No over head of setting up database connections or any other mechanisms of persistence.

 

Yes I know it is old school but is facilitates the requirements for the application I am using. The reason I raise it is because we far to often get caught up in distributed application mentality when something simple like this would do just fine! Below is the enter class file. I hope some one found this useful Smile

 

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;

namespace RabidDog
{
    class Program
    {

        private static void XmlSerialize()
        {
            Dog dog1 = new Dog("Charlie", 42);
            Dog dog2 = new Dog("Jim", 32);


            List<Dog> myDogs = new List<Dog>{dog1, dog2};

            using (Stream stream = new FileStream("MyDogs.xml", FileMode.Create, FileAccess.Write, FileShare.None))
            {
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Dog>), new Type[]{typeof(Dog)});
                xmlSerializer.Serialize(stream, myDogs);
            }
        }

        private static void XmlDeserialize()
        {

            using (Stream stream = new FileStream("MyDogs.xml", FileMode.Open, FileAccess.Read))
            {
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Dog>), new Type[] { typeof(Dog) });
                List<Dog> myDogs = (List<Dog>)xmlSerializer.Deserialize(stream);

                foreach(Dog dog in myDogs)
                {
                    Console.WriteLine("My Dog {0} is {1} years old", dog.Name, dog.Age);
                }
            }
        }


        private static void BinarySerialize()
        {
            Dog dog1 = new Dog("Charlie", 42);
            Dog dog2 = new Dog("Jim", 32);


            List<Dog> myDogs = new List<Dog> { dog1, dog2 };

            BinaryFormatter formatter = new BinaryFormatter();

            using (Stream stream = new FileStream("MyDogs.dat", FileMode.Create, FileAccess.Write, FileShare.None))
            {
                
                formatter.Serialize(stream, myDogs);
            }
        }

        private static void BinaryDeserialize()
        {
            BinaryFormatter formatter = new BinaryFormatter();
            using (Stream stream = new FileStream("MyDogs.dat", FileMode.Open, FileAccess.Read))
            {
                List<Dog> myDogs = (List<Dog>)formatter.Deserialize(stream);

                foreach (Dog dog in myDogs)
                {
                    Console.WriteLine("My Dog {0} is {1} years old", dog.Name, dog.Age);
                }
            }
        }

        static void Main(string[] args)
        {
            XmlSerialize();
            BinarySerialize();
            XmlDeserialize();
            BinaryDeserialize();
        }
    }

    [Serializable, XmlRoot(Namespace = "http://rabiddog.co.za")]
    public class Dog
    {
        public Dog(String name, int age)
        {
            this.Name = name;
            this.Age = age;
        }

        public string Name { get; set; }
        public int Age { get; set; }

        //The XmlSerializer requires a default Constructor
        public Dog() { }
    }
}

Google South Africa 2011–Developers day

By Kenneth 'RabidDog' Clark at November 05, 2011 00:50
Filed Under: Code, Web

Well after the experience of the hackathon I would be lying if I said I wasn’t nervous about attending the developers day. I decided to go anyways and give Google a chance to redeem themselves.

 

well the day didn’t start off very well although the venue was superb. The keynote address was nothing short of uninspiring. The next segment regarding Android development was just as uninspiring. Being at a developers day I was expecting a slightly more in depth presentation regarding Android and not the usual stuff you can pick up anywhere on Google. After the first presentation I decided I was going to ditch the Android track and proceeded to the Google Application Engine (GAE) presentation, hoping things would get better but not expecting it to.

 

Well I was wrong! The Google Application Engine presentation was superb. Opening my eyes to a span of horizons regarding the technology (which I am not going to get into now). With a smile on my face I proceeded to the next mobile presentation which covered some stats. The audience asked some absurd questions that took up  most of the presentation so I don’t think the speaker got to finish. I will get back to the questions in a second.

 

Once he completed his segment we started a code lab using HTML 5 and Google Chrome. YAY! Finally get to do some coding! It was super cool to code along to the presentation and watch the project start taking shape. At the end of the presentation we could finish the application and submit it. By submitting it we would put ourselves in line to win a Samsung Galaxy Ace (S5830). I proceed to keep my head down and complete the project.

 

Will working on the lab, the presentations continued around Google+ (eish) and some start up support project that Google is running with interviews and some inspiration stuff for those that are interested in starting their own business. Having tried this and failed miserably (due to some bad decisions on my part), I am fully aware of the pitfalls and pointers that these individuals were giving so I listened with half an ear. They have some fantastic ideas though, I am looking forward to seeing them come to fruition.

 

Anyways I carried on with the lab and finally finished it. Sitting around a friend of mine asked if I had submitted it for review. This was 20 minutes before the deadline! So I rushed off and had the guys have a look at the lab and they signed it off.

 

Anyways we got to the prize giving and two individuals grabbed what appeared to be two Samsung Galaxy S2 devices. Very cool! Then came the announcement for the winner of the Samsung Galaxy Ace. After going through the process of eliminating contenders, by God’s grace alone, I was chosen as the winner. I gladly accepted the prize but was then asked to demo the lab! I am not much of a public speaker, especially if I am unprepared but I did it anyway. I am not sure the audience understood what I was saying while running through the lab application but at least the one liner at the end got a bit of a chuckle. Oh and for the record, to all you Microsoft haters out there, my code lab was completed using Visual Studio 2010 and hosted on IIS 7.5. So there! Microsoft tools can also get the job done! The right tool for the job.

 

So all in all, the day was a success. Some surprises as to offerings by Google, who seem to also be adopting a cloud service offering and some really cool education regarding HTML 5

 

Thanks Google, for the time, the presentations and the prize. Only piece of advice I have is to perhaps include more labs, less rushed time slots and a little more food at lunch time Smile

 

As for the audience, I urge you to please formulate your thoughts before asking a question. Babbling along trying to create a question and sound intelligent at the same time just puts people to sleep. Make the question short and too the point. Give the speaker the opportunity to respond and leave it at that. Do not engage in a conversation with the individual, it is just rude and inconsiderate to the rest of the audience, if you want to explore your questions more in depth take it offline. Probably the most embarrassing moments for me (as a South African) was the questions around “What Google is going to do for the poor with regard to giving them mobile devices” and then the question regarding what Google was going to do about the fact that a 2 year old device wasn’t going to run the Android Ice Cream Sandwich (Android 4). Lets be honest here, 2 years in the technology space is a long time. I hate to admit it but it is. I also get upset with the fact that we toss out hardware like toilet paper but we cannot expect Google to make sure their Android OS is backwards compatible with the plethora of hardware vendors previous devices. Sure this was a Google Nexus device but let also not kid ourselves as to the maturity of the Android OS. It is a relatively new OS in the grand scheme of things and unfortunately if we are going to be early adopters these are the prices we are going to pay. Perhaps what we should do is petition the device manufacturers to work more closely together with Google.

 

Another thing to remember is that the more backwards compatible a piece of software is, the more bloated it will become. In the mobile space you cannot afford bloat. A mobile OS needs to be lean and tight. Doing only what it absolutely has to. With limited power we cannot go overboard the way we do with our personal computers. (This includes Mac)

 

Well I think I have pretty much covered everything and the next time I will 1) Prepare something for the Hackathon and 2) definitely attend the next developer day.Time to see if I can get a Microsoft developer day in somewhere as well Smile

 

Thanks again to everyone that made today what it was and I enjoyed meeting those that I did and those that I didn’t, well maybe next time Smile

Google Hackathon South Africa 2011–Why Facebook will pwn Google+

By Kenneth 'RabidDog' Clark at November 02, 2011 22:20
Filed Under: Code, Work

Well I must honestly say I was very disappointed. Perhaps I expected to much or didn’t know what a hackathon is about but I didn’t picture it being what happened today.

 

From wikipedia:

“A hackathon, a hacker neologism, is an event when programmers meet to do collaborative computer programming. The spirit of a hackathon is to collaboratively build programs and applications. Hackathons are typically between several days and a week in length. A hackathon refers not simply to one time hacks, but to a specific time when many people come together to hack on what they want to, how they want to - with little to no restrictions on direction or goal of the programming.” http://en.wikipedia.org/wiki/Hackathon

 

Let me walk you through the day. We got there and made ourselves comfortable. It was hosted at Wits university and the venue seemed pretty impressive and I prepared for a good time with like minded people. Then it started. First we got a presentation from one of the GTUG members (Google Technical User Group or something). The presentation made me feel like I was back in high school being subjected to an English speech that was not prepared before hand.

 

Then we moved on to a video call from one of the Google developers in the UK or somewhere. Myself and others spent most of the time lip reading what the guy was saying as we couldn’t hear anything! So you sit wondering what you missing and people started getting distracted and then the whispering and conversations start. Things are going down hill fast. Video call ends and then we move on.

 

Next we get what can only be described as a whirl wind trip through using OpenAuth presented in Ruby. I still cannot remember anything from the explanation other than the individual presenting was a Ruby expert of sorts.

 

Moving one we were issued with the orders to build something using the Google+ API. Cool! Lets get cracking. Start investigating the Google+ API and get the fright of my life. The API only supports read requests. I kid you not, the social application said to be Facebook’s major competitor only has read access via the API. WHAT! So I mean really how hard can it be to make an HTTP request, receive a JSON formatted response and render that data. This is where things get really interesting.

 

I was under the impression that a hackathon was an event where everyone starts from scratch and starts nailing things together. How wrong I was. It seems that terms in the software industry are nothing more than marketing hype. Upon beginning development I started noticing that groups were getting ready to deploy their applications. What is going on here? Well it seems that there where a few groups who had actually developed their applications prior to the “hackathon” and merely brought them along to present. Now, again, I am not sure if I am just the idiot, but I am certain the title of the event was hackathon not exhibition?  The event then proceeded to run an hour over time with myself and a few others extremely disillusioned about the entire event. Towards the end of the day I couldn’t help but look forward to being told the day was over so I could go home.

 

Sorry Google but I think you missed the mark with this one. Your Google+ API is wafer thin and offers nothing. If you are hoping to regain the traction you initially had I would recommend you start allowing developers to push and pull data from different applications and platforms. There is nothing that separates your social network site from Facebook and by virtue of the fact that the majority of the market is on Facebook, you really need to give people a reason to use Google+. I signed up for it with great expectations when it became available. Since then my usage has steadily decreased to next to nothing.

 

That being said, I am really hoping that the developers conference on Friday makes up for today because today was truly disappointing. That being said, the gapping holes in the API and client interfaces has given me an idea for a new open source project.

Jenkins, Glassfish 3 and Windows 2008 R2

By Kenneth 'RabidDog' Clark at October 06, 2011 23:51
Filed Under: Java, Code, Web, Continuous Integration

Right lets get cracking. First thing you going to want to do is grab the Jenkins files available at http://mirrors.jenkins-ci.org/. Select the package you looking for. The WAR file is the web application deployable to containers such as Tomcat or Glassfish. There is also a standalone version but seeing as I want to brush up my Glassfish skills I decided to grab the WAR file.

 

Now this is were I generally start getting extremely nervous. In my experience, deploying these things on app servers is always a nightmare requiring tweaking and additional work. So here we go.

 

In the Glassfish administration console, select the applications link. This will give you a list of currently deployed applications on the server. Right now I have zero Smile So, select the deploy button on the grid header, select the browse button and navigate to your jenkins.war file.

 

Once you have done all this you will notice that Glassfish has conveniently detected that it is a web application, suggested a context root and an application name. Select the the item “server” in the virtual servers list and make sure “Enabled” is checked. Proceed to select anything else you want the server to handle. I just want to get this deployed so I am going to keep it minimal. Once you are satisfied click the “OK” button on the bottom right of the page. I was pleasantly suppressed to see that the deployment went off with out a hitch! If successful you will be returned to the Applications list with jenkins listed there now. On the right of the grid you will see links to perform actions. Select the “Launch” link. This will take you to a web page giving you the URL for the http location and the https location.

 

Click the link you want and wait for jenkins to perform it’s initial operations. If all goes well, you will be presented with the dashboard to perform your configuration and maintenance.

 

Just as a side note, having been involved with Glassfish 1 and 2 then slacking off during development of 3 I must admit that the level of the application server has increased significantly! I am very impressed at how the admin UI has been fixed and the ease of use and deployment. Hats off to the development team.

 

Oh, just as point, for those that think they have to go buy super powered machines, this box is running 1GB RAM with one of the first AMD 64 bit processors and runs fine, so now need to empty the wallet just yet Smile Bear in mind that this is a personal machine so it isn’t subject to huge loads. Will do some stress testing and see where it gets me.

 

Other than that, have fun!

Setting up a local (private) GIT repository

By Kenneth 'RabidDog' Clark at October 04, 2011 01:49
Filed Under: Code, Open Source

I don’t claim to be an expert regarding the use and configuration of GIT but this evening I did manage to get a local repository up and running. The reason I am switching from SVN is because I really like the ease of use and being part of http://github.com it is best I get up to speed on GIT.

 

I am just going to list a few articles I found that helped me get everything running. There are a few things I need to sort out, like the RSA keys and authentication using them but I will handle that another time, for now I don’t mind typing in my password. Please note that I setup my repo on a Windows machine.

 

Well without further delay, here you go:

 

Initial setup

http://therightstuff.de/CommentView,guid,b969ea4d-8d2c-42af-9806-de3631f4df68.aspx

http://www.shannoncornish.com/blog/2009/04/git-server-windows-2008/

 

Client setup

http://www.devillex.com/2011/02/10/setting-up-git-on-windows-and-visual-studio-2010/

 

Setting up a public repository

http://book.git-scm.com/4_setting_up_a_public_repository.html

 

Deleting a repository

http://stackoverflow.com/questions/1213430/how-to-fully-delete-a-git-repository-created-with-init

 

Some interesting side notes

http://stackoverflow.com/questions/804545/what-is-this-git-warning-message-when-pushing-changes-to-a-remote-repository

http://www.gilesthomas.com/?p=379

JavaScript Hashmap and MVC 3

By Kenneth 'RabidDog' Clark at September 22, 2011 23:00
Filed Under: C#, Code, JavaScript, Web

I was fiddling with an idea that allowed rows to be dynamically added to an html page and deleted off the page. This became a bit tricky because I couldn’t identify the row I wanted to get rid of.

 

Eventually what I ended up doing was maintaining a list of the rows in a JavaScript object that functioned the same as the hash map and as opposed to deleting one row at a time I would remove the entire list from the page and re render it. The reason for this is when submitting arrays to an MVC 3 controller based on a strongly typed model you have to name the hidden input fields sequentially. Something like this:

 

<input type="hidden" id="EventList_0_SomeId" name="EventList[0].SomeId"  value="myid" />
<input type="hidden" id="EventList_0_Capacity"  name="EventList[0].Capacity"  value="25" />

 

As you probably gathered the next one would increment the 0 in the id and the 0 in the name to 1. The next one 2 and so on and so forth.

 

<input type="hidden" id="EventList_1_SomeId" name="EventList[1].SomeId"  value="myid" />
<input type="hidden" id="EventList_1_Capacity"  name="EventList[1].Capacity"  value="25" />

<input type="hidden" id="EventList_2_SomeId" name="EventList[2].SomeId"  value="myid" />
<input type="hidden" id="EventList_2_Capacity"  name="EventList[2].Capacity"  value="25" />

<input type="hidden" id="EventList_3_SomeId" name="EventList[3].SomeId"  value="myid" />
<input type="hidden" id="EventList_3_Capacity"  name="EventList[3].Capacity"  value="25" />

Just as a pointer, the name and the id of the input have to be declared or the MVC 3 controller will not resolve the values. The above example is a model that contains a list of objects that contain a property called SomeId and Capacity. If you do it the way I have illustrated above, it will resolve into a nice object representation in the controller that you can manipulate.

 

The Hashmap declaration:

function Map()
{
    // members
    this.keyArray = new Array(); // Keys
    this.valArray = new Array(); // Values
        
    // methods
    this.put = put;
    this.get = get;
    this.size = size;  
    this.clear = clear;
    this.keySet = keySet;
    this.valSet = valSet;
    this.showMe = showMe;   // returns a string with all keys and values in map.
    this.findIt = findIt;
    this.remove = remove;
}

function put( key, val )
{
    var elementIndex = this.findIt( key );
    
    if( elementIndex == (-1) )
    {
        this.keyArray.push( key );
        this.valArray.push( val );
    }
    else
    {
        this.valArray[ elementIndex ] = val;
    }
}

function get( key )
{
    var result = null;
    var elementIndex = this.findIt( key );

    if( elementIndex != (-1) )
    {   
        result = this.valArray[ elementIndex ];
    }  
    
    return result;
}

function remove( key )
{
    var result = null;
    var elementIndex = this.findIt( key );

    if( elementIndex != (-1) )
    {
        this.keyArray = this.keyArray.removeAt(elementIndex);
        this.valArray = this.valArray.removeAt(elementIndex);
    }  
    
    return ;
}

function size()
{
    return (this.keyArray.length);  
}

function clear()
{
    for( var i = 0; i < this.keyArray.length; i++ )
    {
        this.keyArray.pop(); this.valArray.pop();   
    }
}

function keySet()
{
    return (this.keyArray);
}

function valSet()
{
    return (this.valArray);   
}

function showMe()
{
    var result = "";
    
    for( var i = 0; i < this.keyArray.length; i++ )
    {
        result += "Key: " + this.keyArray[ i ] + "\tValues: " + this.valArray[ i ] + "\n";
    }
    return result;
}

function findIt( key )
{
    var result = (-1);

    for( var i = 0; i < this.keyArray.length; i++ )
    {
        if( this.keyArray[ i ] == key )
        {
            result = i;
            break;
        }
    }
    return result;
}

function removeAt( index )
{
  var part1 = this.slice( 0, index);
  var part2 = this.slice( index+1 );

  return( part1.concat( part2 ) );
}
Array.prototype.removeAt = removeAt;

 

The usage is just as simple. Include the JavaScript file and then:

var map = new Map();

map.put("key", value);
map.remove("key");

//etc

 

A really nice feature is that it does not duplicate keys but performs an “update” on the object at that key. So if you want to retrieve all the keys you can do something like this:

 

for (var i = 0; i < hashMap.keyArray.length; i++) {
    var value = map.valArray[i];
    var key = map.keyArray[i];
    console.log(key, value.toSource());
}

 

 

I found the Hashmap declaration over here http://freecode-freecode.blogspot.com/2007/06/hashmap-object-in-javascript-like.html

 

Some other interesting tid bits on the MVC embedded arrays, lists and editors for:



I am South African. Always have been always will be. I love my country. I love my wife and two children.


I also really enjoy solving problems. I currently work as a Software Architect exploring new solutions for business problems. Having been round the block a few times I enjoy showing new developers how best to solve problems, how to find answers and how to approach solution development.


In my spare time I enjoy riding my super bike, training in Systema and horsing around with my family.


Month List

Visitors

Twitter Feed

20. February 21:10
@telkomsa saying a pending R4.2 billion fine could sink them, I say sink them! Tired of paying for (no) service.

19. February 22:39
@telkomsa congratulations! This is a new record regarding no/intermittent service! Just over 2 months tossers! And I still pay for it

6. February 18:01
Unit tests don't check if code works. They PROVE the code works!

12. January 23:34
@Annaling horrific. People like that should face sever punishment. Unless of course they tried to find the cat :(