Life on Rails » Technological travels in Flex, Air, RIA and life in general
Imagine a beautiful autumn park, and a bald ginger man reading books and playing guitar, and doing other stuff

Running flexunit ant task on headless linux

I’ve had endless trouble with this. As it goes, I don’t much like Ant, I’d rather use maven, but flashbuilder is nowhere near up to scratch with m2elipse right now. As such, I’m stuck with ant and flexunit ant tasks..

I’ve wasted hours trying to get this going on headless linux, but finally the answer became clear. A friend of mine pointed out that peter Ent’s flexunit task makes a call to gflashplayer instead of flashplayer. So I do the following:

  • create bash script called gflashplayer with this command:xvfb-run flashplayer $1,
  • ensure that the swf you are executing is stored in a trusfile. I have an ant task that adds the swf to the file antUnitTests.cfg stored in: ~/.macromedia/Flash_Player#Security/FlashPlayerTrust/

I also turn on logging by having an ~/mm.cfg file with the contents: ErrorReportingEnable=1 TraceOutputFileEnable=1

This helps, as you can trace -f the log file generated at ~/.macromedia/Flash_Player/Logs/flashlog.txt

I’m so glad to finally have this resolved. I hope this helps you get flexunit integrated with ant on hudson, teamcity or whatever other ci you have on headless linux too!

Code formatting in Flashbuilder

Got the flashbuilder 4?

It’s really much better than flexbuilder, I suggest you download it straight away!

Anyhow, that’s not why I’m writing. The reason is that there’s a great code formatting plugin I’ve discovered for automatically formatting mxml and actionscript code.

It’s great!

  • flexible – you can configure it yourself,
  • powerful – works for as and mxml,
  • quick,
  • has extra benefits, like gives you quick headsup if you have silly errors, without having to spend a compile cycle,
  • can share the settings with your team (via import/export) which makes it really easy to enforce coding standards,
  • saves loads of time – just click a button before submitting your file!

Loving it! the plugin is named flexformatter and is availabe here: http://sourceforge.net/projects/flexformatter/!

DONT DELAY – download it!!

Install instructions are on the link, it’s real easy to install..

making ant nicer

Tags: , , ,

As I said in my previous post, ant get’s my goat..

the ant-contribe project makes it easier to live with by adding a whole suite of tasks that make it more bearable by adding common coding constructs, like foreach, if, trycatch and MUTABLE VARIABLES! (discouraged, I know, but useful sometimes ;) ).

FInd it here:

http://ant-contrib.sourceforge.net/tasks/index.html#install!

Passed Java scjp 6

So chuffed!

Passed the scjp 6 exam with 77% !

Did it mainly so I could get my Java up to speed and hit the ground running with Blaze ds, Livecycle or other Java backend’s sitting behind Flex, as I envisage it will be very useful to me in the future.

The exam is REALLY HARD. The questions are so sneaky! I had to do quite a bit of learning for this, as I haven’t learned any new java since java 3. I had to learn all of the new generics, collections and enums too! In fact, asserts as well!

It’s a great way to focus your learning though – I’m not going to pretend I know dick about Java in the workplace, because I would need some proper exposure before making claims, but that’s not the point: The point is that I can now pick up Java without having to worry about the basics, I’ll be able to spend my time learning the api’s of the technology I’m using rather than spend it learning Java syntax and concepts.

Was very insightful too – also made me realise just how horribly lacking actionscript is! Still, as has some lovely rough and ready elements to it that retain its’ charm :)

So, yeah – if you’re thinking of doing it and you’re not a full time Java bod, expect to revise real hard!

Next up is the flash exam – that one should be a walk in the park compared to Java :D

messing about with components inline with text

Tags:

This is more a note to myself,

I’ve got my smiley textarea, but I’m going to rewrite the whole thing from scratch.

Before I do, heres some code I need in the office tomorrow! Might be of use to you too..



<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
    layout="vertical" 
    creationComplete="cc()" xmlns:local="*">
    <mx:Script>
        <![CDATA[
            import mx.controls.TextInput;

        private function cc() : void
        {
            var ti : TextInput = new TextInput();
            ti.width = 100;
            ti.height=18;
            t.clip = ti;
            t.targetText = "APPLE";
            t.text = "here is an APPLE and some text to wrap around it, hopefully" + 
                    "it will be nice";
            t2.text = "here is an APPLE and some text to wrap around it, hopefully " + 
                    "it will be nice";
            ti = new TextInput();
            ti.width = 100;
            ti.height=18;
            t3.clip = ti;
            t3.targetText = "APPLE";  
            t3.text = "APPLE is an and some text to wrap around it, hopefully " + 
                    "it will be nice";
            ti = new TextInput();
            ti.width = 100;
            ti.height=18;
            t4.clip = ti;
            t4.targetText = "APPLE";
            t4.text = "here is an and some text to wrap around it, hopefully " + 
                    "it APPLE be nice";
        }
        ]]>
    </mx:Script>

    <local:SuperText id="t" width="300"/>
    <local:SuperText id="t2" width="300"/>
    <local:SuperText id="t3" width="300"/>
    <local:SuperText id="t4" width="300"/>
</mx:Application>


package
{
    import flash.display.DisplayObject;
    import flash.text.TextField;
    import flash.text.TextLineMetrics;

    import mx.controls.Text;

    public class SuperText extends Text
    {
        public var targetText  : String = "APPLE";
        private var measurer : TextField;
        private var space : int;
        private var targetTextWidth : int;
        private var lineHeight : int;

        public function SuperText() 
        {
            super();
        }

        override protected function createChildren() : void
        {
            super.createChildren();
            measurer = new TextField();
            measurer.visible = false;
            addChild( measurer );
            textField.text = " ";
            space = textField.textWidth;
            textField.text = targetText;
            targetTextWidth = textField.textWidth;
            lineHeight = textField.getLineMetrics( 0 ).height;
        }
        private var _clip : DisplayObject;
        private var clipChanged : Boolean;
        public function set clip  ( value : DisplayObject ) : void
        {
            _clip = value;
            clipChanged = true;
        }

        public function get clip() : DisplayObject
        {
            return _clip;
        }

        override protected function updateDisplayList(w:Number, h:Number):void
        {
            super.updateDisplayList( w, h );
            measurer.width = w;
            measurer.height = h;
        }

        override protected function commitProperties() : void
        {
            if ( clipChanged && clip )
            {
                addChildAt( clip, numChildren );
                clipChanged = false;
            }
            super.commitProperties();
            updateTextLayout();
        }

        override public function set text(value : String ) : void
        {
            super.text = value;
            measurer.text = value;
        }

        private function updateTextLayout() : void
        {
            if ( !clip ) return;
            var i : int = text.indexOf( targetText );
            //calculate how many characters to replace
            var chars : int = clip.width / space;   
            textField.text = textField.text.replace( targetText, makeSpace( chars -1) );
            var l : int = textField.getLineIndexOfChar( i );
            var offset : int = textField.getLineOffset( l );
            var subText : String = textField.getLineText( l ).substr(0, (i +1) - offset );
            measurer.text = subText;
            var lm : TextLineMetrics = measurer.getLineMetrics( 0 );
            clip.x = lm.width;
            clip.y = lineHeight * l;
        }

        private function makeSpace( n : int ) : String 
        {
            var s : String ="";
            for ( var i : int; i < n; i++ ) 
            {
                s+=" ";
            }
            return s;
        }

    }
}

I passed my Adobe Flex 3 and Air exam

Adobe Flex 3 Certified Expert

Adobe Flex 3 Certified Expert :D

Just a note to say I passed my flex 3 and adobe air exam. I got 90%, which is ok, but tbh, I thought I could’ve/shoud’ve got a hundred, the exam is actually quite easy, as it goes.

I think the flex 2 exam is much, much harder, and I’ll certainly be advising recruitment agents I know to look for candidates’ with both, as I reckon the 3 certification is much more blaggable than the flex 2 certification (I don’t think that was blaggable, actually).

My score breakdown is as follows:

  • Total 90%
  • Creating a user interface 100%
  • Flex system architecture 88%
  • Programming flex applicaitons with actionscript 91%
  • Interacting with data sources and servers 87%
  • Using Flex in the Adobe integrated runtime (AIR) 80%

I never used Adobe Air before friday, and made a cute little app in it yesterday to get to grips with the features (I’ll be blogging about that here and on georgcook.org, in the near future). Other than that I watched some lynda training vids on Air (lynda training is a must for any new technology imho), and just skimmed through my old revision notes. So if you’re about to take the exam, take a look at my notes about flex 2.

I didn’t use ATest this time round, as Dave, the very nice guy at PXL is too busy, and possibly a little bit unfocused on just making a mock test for it : he’s trying to make some sort of education platform, which is great of course, but he must be losing an awful lot of ATest sales.

Regardless. If you’ve worked with flex for anytime it will be a breeze. If not : READ THE DOCUMENTATION. Noone ever does this. I work with people who never read the manuals – it’s so dissapointing, especially when these guys come from Java, or .NET and think they know it all, but have never even opened the user guide, other than to solve a specific problem.

So there you have it kids. It’s easy, don’t stress about it, and read the docs. You’ll breeze through it.

Better LayoutManager, Hybrid VBox, Hyrbid HBox

This is a follow on from my previous post asking if you are getting the most out of includeinlayout, well I wasn’t and I was sick of code like this:

  1. <VBox>
  2. <Component1 />
  3. <canvas>
  4. <text left=20 text="the point of this is only to have an indent of 20 for this one item i the vbox" />
  5. </canvas>
  6. <Component3 />
  7. </VBox>

The problem is that the LayoutManager used by Box (BoxLayout), though efficient and powerful, doesn’t allow for the concept of margins. In flex we can pad within a component, but any component we make can’t add a margin around itself.

I’ve got here a crude exmaple which covers the majority of cases that I would normally want, and can cut out most of the need for the extraneous canvas above.

With the hybrid vbox (HVBOX) you can do the following:

  1. <local:HVBOX>
  2. <mx:Button width="200" label="test" />
  3. <mx:Button width="200" label="test2"
  4. top="20"
  5. left="20"
  6. right="20"
  7. />
  8. <mx:Button width="200" label="test3"
  9. top="5" />
  10. <mx:Button width="50" label="test FLOAT"
  11. y="15" x="100"
  12. includeInLayout="false" />
  13. </local:HVBOX>

In the previous code examples, the top, left, right and bottom properties will apply a margin around the control. This syntax works for vbbox and hbox alike, and in both cases, will cause the control to shrink on the axis that is not being stretched (e.g. if you set margins left and right on a compoenent in the vbox, then the control will shrink left and right to fit in with the rest of the vbox, thus giving you padding on an individual basis ).

While I was at it, I also added a simple refinement that means you can mix non vbox laid out components as well as vbox laid out components, look at the last component. It has includeinlayout set to false, but visible is true. Note the x and y settings, these will be observed WITHIN the vbox – no need to layoutchrome or wrap in a canvas. :D

This can be further improved for sure (my measuring is very crude), but as I said this catches the majority of cases I need. oh, and the name sucks as I only whipped it up in 20 minutes to blog to you here, dear reader:

More...

cheeky so and so

I can’t believe this.

I was just hunting around for anyone who has passed the flex 3 cert (which I am studying for, to update my flex 2 cert),.. incidentally an Indian chap has – Venkat Viswanathan – Well done!!

yeah, so I was looking about, and if you recall, when I did my Flex 2 ACE, I posted up on here about my notes and what I was up to..

Here’s a picture of their blog ( wont give the cheeky fucks the trackbacks ): My hard earned notesl

Look familiar? http://www.lifeonrails.org/2008/2/26/i-passed-my-adobe-flex-exam+

these little herberts are taking my hard earned notes, and pasting them on their blog to pretend they did the work? What a cheek!?

Are you getting the most out of includeInLayout?

I often see code in many flex apps that looks like this:

  1. <mx:Canvas>
  2. <VBox>
  3. <Component1 />
  4. <Component2 />
  5. <Component3 />
  6. </VBox>
  7. <!- the following component is required to be place above both component 1 or 2, or the background underneath 1 or 2 ->
  8. <Component4 x="20" y="100">
  9. </mx:Canvas>

The requirement to have component4 absolutely positioned, while the rest of the componets are positioned in accordance with a layout manager causes an extra container to be added. I’ve also seen this worked around by using the chrome (which I do myself when making template ViewStacks).

I’ve recently made a lovely discovery (well, more like seen the patantly obvious). We all know that since flex 2.01, if you have a container with managed layout (such as a subclass of Box) that you can use the includeInLayout property to opt out of the layout scheme. We often use this in conjunction with the visible property.

God knows why, but it seems myself or others haven’t considered using this to achieve a hybrid of absoulte/managed layouts.

I’m currently using this to great effect. To make it work the absolute position of your components that will be laid out manually must be set after the children are laid out. You can achieve this by using the CreationComplete event. In the cases where you envisage the layout changing after creation has occurred youy can override updateDisplaylist.

Here’s an example

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300"
  3. creationComplete="onCreationComplete()">
  4. <mx:Script>
  5. <![CDATA[
  6. private function onCreationComplete() : void
  7. {
  8. absoluteInAVbox.move( 50, 25 );
  9. }
  10. ]]>
  11. </mx:Script>
  12. <mx:Button label="one" width="100%" height="50"/>
  13. <mx:Button label="two" width="100%" height="50"
  14. includeInLayout="true"
  15. />
  16. <mx:Image
  17. id ="absoluteInAVbox"
  18. includeInLayout="false"
  19. height="50" width="100"
  20. >
  21. <mx:source>file:////Users/georgecook/Pictures/Photo Booth/Photo 3.jpg</mx:source>
  22. </mx:Image>
  23. </mx:VBox>

While I’m at it – .move is far better than .x and .y, as the latter cause the displayObject to invalidate. ;)

Nicer navigation

  1. //model class
  2. private var selctedView : int;
  3. public static const VIEW_FIRST_SCREEN : int = 0;
  4. public static const VIEW_USER_PROFILE : int = 0;
  5. pubic static const VIEW_USER_PROFILE_SUB_SCREEN : int = 0;
  6. //a view, that uses the model class as a pm
  7. <ViewStack id="fubar" selectedIndex="{model.selectedView}" />
  8. <ButtonBar id="viewSelection" click="model.sleectedView = viewSelection.selectedIndex" />

I hate the selectedIndex property of viewstack – I find it always leads to the messiest, most difficult code. Many times too many, I’ve had to refactor a part of an application that has ended up with terribly unreadabe and fragile code as a result of index constants, I think the reasons are as follows:

The indexes are initially for one or two things, as the app is in its’ first iterations,

  • More indexes and views get added,
  • People are busy, so they use the indexes to derive other variables, or for logic,
  • Over time the dependencies on the index constants are far greater than just the the selected view, as more and more code has been added referring to the index constats,
  • Around this point, someone wants to add a new view, or change the order of views – usually what happens then is that instead of refactoring the indexes, people tend to tack on sub viewstacks, and sub viewstack indexes that go with them, to facilitate the edge cases these new views have brough with them,
  • With another layer of indexes the code is even more fragile, even harder to refactor, even harder to maintain and nye on impossible to read – ladies and gentlemen, please start dumping crap code in this class after 3.. 2.. 1..

There have to be better ways of doing this – here’s one I use a lot – I’ve included the abstract code as well, it’s slightly longer to read, but I think it’s much more simple and much more maitainable, and easier to work with

  1. //MyView
  2. <ViewStack id ="clearer" selectedIndex="{model.selectedViewIndex}" />
  3. <ButtonBar id="viewSelection" click="model.selectedViewIndex = viewSelection.selectedIndex" />
  4. //My PM
  5. class MyPM exteds BasePM
  6. {
  7. override protected function initializeViews() : void
  8. {
  9. welcomeScreenPM = new WelcomeScreenPM();
  10. userProfilePM = new UserProfilePM();
  11. userProfileSubScreen = new UserProfileSubscreenPM();
  12. views = [ welcomeScreenPM, userProfilePM, userProfileSubScreenPM ];
  13. }
  14. }
  15. //base model class
  16. [ArrayElementType("com.gc.BasePM")]
  17. private var views : Array; //of BasePM
  18. constructor()
  19. {
  20. initializeViews()
  21. }
  22. protected var initializeViews() : void { //abstract }
  23. private var _selectedView : BasePM;
  24. [Bindable]
  25. public function get selectedView() : BasePM
  26. {
  27. return _selectedView;
  28. }
  29. public function set selectedView( value : BasePM ) : void
  30. {
  31. _selectedView = value;
  32. dispatchEvent ( new Event( SELECTED_VIEW_CHANGED ) );
  33. }
  34. [Bindable("selectedViewChanged")]
  35. public function get selectedViewIndex() : int
  36. {
  37. return views.indexOf( selectedView );
  38. }
  39. public function set selectedViewIndex( value : int ) : void
  40. {
  41. selectedView = views[ value ];
  42. }

Now, pedant’s amongst you are free to point out that I should put the sub view in the initializeviews of user profile, and that is true, and possible, and desirable – however, this is only an example of an alternative to indexes with constants – as always, please post improvements – and it probably wont compile straight off, I just hammered it out as text, I’m sure it reads clearly though :)

bubbling non ui Events

Really nice handy little tip this.

Say you have a model, which has a child model, and you want the child to bubble events to the parent (most common use I have for this is binding). I used to make an event listener on my parent, and then dispatch a new event for the child. There’s a much better way of doing this..

simply set the eventhandling method to be dispatchEvent.. e.g.

myChild.addEventListener( AN_EVENT, dispatchEvent );

Clearly this assumes that your class (parent of myChild) extends/implements event dispatcher. It’s soo obvious, I don’t know how I missed it all this time!

TDD or not TDD, that is the question

I’ve seen the light. For so long I thought I was doing TDD, I thought I was being agile, and I hate to admit it, but I wasn’t. I was trying too hard. I was thinking too much, and secretly holding to fears and misconceptions that were stopping me from realising the benefits of some of the best agile practices.

I’m not hung up or bummed out though – it was fair enough really – the project’s I was on didn’t really allow for a truly agile approach for the majority of the time. The fact is you have to breathe out before you breathe in, and I was in a situation where there was no breathing space at all.

But I eventually did get some breathing space, and a neat reading list and as fate would have it, that coincided with one of those periods that we all get as software engineers, where you get real hungry. I’m not talking raid the fridge hungry, I’m talking knowledge hunger – process hunger, efficiency hunger.

I’ve been lapping up some great stuff and it made me see where I was going wrong in a lot of areas. The biggest one I came to realise was that I wasn’t really doing TDD.

I kept trying, but I’d always buy into THE OLD LIE. You know – “it takes too long to write the test up front, I’ll just nip back later”. Recently though, I sat myself down after my latest book bout and had a word with myself.. what was stopping me from doing this?

It turns out it was actually something quite simple – it took so long for me to compile and run tests on the projects that I was in, that I had a skewed opinion of TDD. I was literally associating the amount of time it took to build and run a full testrunner (often times in excess of 800 tests) with TDD. In short I had been foolish.

I think it was the nazareen who said “if thy eye offends thee, tear it out”, which though seemingly grim, is actually good advice. And tear it out I did.

I basically came to a new understanding – this is it: The testrunner is the total suite of tests for the entire application, The testrunner is the docuemntation of the API’s of the entire application, The testrunner is ueful for regression, The testrunner is useful when building to ensure the application is in a healthy state, The testrunner actually is more and more depending on how many books you read, and how good your memory is.

One thing the testrunner is NOT however, is a harness for doing TDD.

This has been my single biggest leap in understanding of TDD. Quite simply the apps I work on are so big that building and running the entire testrunner in order to do TDD is simply unbearable.

On my last project some of us would sometimes remove all the tests from the testsuite, save 1 or 2 (remember, if thy eye offends thee – tear it out ;-) ). However, we never formalised this process – sometimes with disastourous consequences: You’d run the testrunner and find someone had deleted ALL of the tests in the app.. Looks like that build that went out might have only gone out with 1 out of 1,000 tests being run on it..

I can’t believe how obvious the answer is.. I just made a new rig – TDDRunner.mxml, and a new testsuite AllTDDTests.as. It’s really simple – each developer has their own AllTDDTests file which they keep the tests in that they need at any given time, and never check it in.

I’ve been doing this for a week now and with great results. I’m genuinely able to do TDD without any painful overhead, waiting for the compiler, or other tests, or risking deleting the testuites, or without even losing concentration. It’s a dream come true.

As I write the tests, I add them to the main testrunner, and I run this whenver I reach a mile stone (such as finishing a presentation model, or a domain model ) to ensure that regression is not caused elsehwere.

I cannot emphasize enough how great the benefits of this approach are. Myself and a couple of colleauges are literally buzzing off TDD as a result of this. It’s also much easier to sell to others who are usually closed to it.

It’s gone from barely being able to justify it to some colleagues to the point where they now have no excuse for not doing it.

Perhaps with other languages this isn’t such a problem, but with actionscript, or I suspect with any app with a large testsuite, I suspect this simple process improvement will lead to more developers practising TDD.

FlexBug.. well sort of

I’ve been a huuuge fan of firebug for sme time and longed for a version for flex. FlexSpy has been around for some time, and is really great, but it needed a bit more, especially in terms of invoking it. Currently it has this target button, but it’s a bit naff, and slow..

As such, I’ve taken some code I’ve posted about earlier, and some more code from the great Ralf Bokelberg – to create FlexBug.. it might be cheaky using this name, or indeed using the excellent flexspy code like this, but wtf afterall flexspy is released under the wtf license ;-) (check if u don’t believe me).

The new changes allow you to right click on the stage and it will list a child hierarchy – selecting any element opens that element up in flexspy – making it easier to identify ui components and also quicker (no more parsging tons of xml inside the swf).

I’ve also added FlexTrmp to this as well – which can allow you to execute rudimentary actionscript in real time.

The parser is shite – sorry, it’s just a spike that I’ve never had time to improve, but still – there’s basic code completion, object inspection and code snippets.

Further more – if you hold control while clicking on object’s that are in flexspy view (e.g. presentation models, or other classes) a variable will be created in the code console.

why?

The motivation is simple – I wanted a simple means of getting maximum use out of every build. I’ve worked on a cuple of projects now with huge build times, and I hated when something screwed up that stopped me verifying some functionality. Ok TDD theoreticaly prevents this, but we all know there are frequent exceptions to this, and moments when we wished we could hack about – especially when investigating defects, familiarising with new code or working on spike’s.

I hope you find this combination of flexspy and the ContextMenuItemProvider and FlexTramp helpful. I’ve also included the excellent IsDeveloperVersionChecker, also from Ralf – if you look at the downloaded rig project you will be able to see it’s use – check the compiler args for more info.

Please – no gripes about code etc.. as I said it was only a spike – if anyone seriously want’s to take this on and turn it into a proper open source project – well please let me know.

For working example visit:

for source code download this. flexbugalpha download !+

For more info on flextramp – see my flextramp blog post -it has syntax, etc..

please note – I’m doing this off dial up speed internet (damn bt so much) – my connection is so slow that I can’t really upload working example’s etc yet – you’ll have to trust me and download the zip.

once I got my broadband connection, I’ll upload proper examples and screenshots here..

Animating text in flex - solving scaling problems

I’ve been working on a project recently and made a pod component. There’s a requirement which has the text animating on the pods as they scale up and down. However, we’ve been stuck because the text animation is jerky and jittery and looks wrong.

There are lots of pages about this problem, and the solutions vary from making bitmap data copies (which look crap when they scale up), to using flash, to some random things involving font embedding tags.

However,none of them work – but one of my colleagues stumbled upon the solution..

Use this tag. fontGridFitType

It’s used like this:

here’s a snippet:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
  3. <mx:Text id="jerky" text="some jerky text" />
  4. <mx:Text id="smooth" text="some smooth text" fontGridFitType="none"/>
  5. <mx:Zoom id="grow" targets="{ [ jerky, smooth ] }"
  6. zoomWidthTo="3" zoomHeightTo="3" duration="2000"/>
  7. <mx:Zoom id="shrink" targets="{ [ jerky, smooth ] }"
  8. zoomWidthTo="1" zoomHeightTo="1" duration="2000"/>
  9. <mx:Button label="eat me" click="{ grow.play() }"/>
  10. <mx:Button label="drink me" click="{ shrink.play() }"/>
  11. </mx:Application>

The reason it works is beacuse if the fontGridtype is set to anything other than none , it plays with the kerning horrendously (making the letters land on pixelboundaries) – which makes it appear jerky.

I was sOOO glad to find this out – it was driving me mad!!

Have fun with it.

1and1 does it again, great hosts

Just a short note to say that I truly love the web hosts 1and1. That’s who my server is hosted with, and who is responsible for hosting all of the sites I have.

They have great dedicated server packages that are super fast, with loads of bandwidth. I actually run visualchat.co.uk on on of their dedicated servers, which has ample bandwidth for all the audio and video of the webcam chat sessions.

In short,

  • the servers are fast,
  • they got great control panels,
  • the support is actually really good, both written, and on the phone,
  • the bandwidth is phenomenal,
  • you get free ftp backup with each dedicated server,
  • they never go down.

They really are great – I strongly recommend them… However, I’m not writing because of that – I’m writing to let you know that they have exceeded my expectations again:

In September 2007 I took up a new server package, a beefed up dedicated server, that came with 3 months free contract, then 18 months minimum term. Now, I was intending to migrate my existing dedicated server (contract expired) to the new server.

However, I started working for Adobe, and was so busy that I never got a chance to move the server, and therefore ended up paying for both dedicated servers. Now 1and1 get a few bad reviews for locking people into contracts, but I have to say – they were great with me – I called them, explained what had happened, and they simply asked me to fax them the details.

The server is now cancelled: Including the 18 month contract! Yep! they just let me back out of it, by being reasonable and human about it all – so next time someone tells you that they are monsters, and hold people in to contracts, I suggest you ask them how they spoke to their staff, and how they treated them – I know other people who have been rude, and they get what they give..

I don’t know any other host that would do this – I can definitely tell you 3 other hosts that wont budge at all on these matters (though I don’t want to name them)...

BTW, I’m not an affiliate – I haven’t joined their program, so I’m genuinely objective – check them out if you want dedicated servers- for any small-medium scale project (read as, don’t need a server farm and fail over), they’re great!