Blog Moved ....



my book(s)

my products

Extending Sys.StringBuilder with an appendFormat method

I love working with the new objects in JavaScript available in the AJAX framework. There is a new Sys.StringBuilder, which looks/acts/feels just like the server side StringBuilder does.

There is also an extension to String for a format(mask, [args]); method that let's you do a nice replacement of a string mask.

String.format("{0} is before {1}", "This", "That") give your a nice single string of "This is before That", just as you'd encounter on your Server side.

But Sys.StringBuilder doesn't have an appendFormat(mask, [args]) like String does, it only has a append, and an appendLine() method.

So let's create a new ScottCate.StringBuilder that inherits from Sys.StringBuilder, and prototype an appendFormat() on it.

I'm not very happy with the arg0....arg9 in the appendFormat() signature, but that was easier than reflection style code against the arguments.

Oh! And special thanks to my friend Michael, who helped me figure out the toString() problem I was having.

[UPDATE] Man-o-man you gotta love blogging. A few hours after I posted this, I received a tip about the Function.apply() method. I can't believe after all these years, I'm still finding these nuggets in JavaScript. apply() allows for the arguments that were passed into the method (err function) to be passed onto another method (I mean function). So now as many strings as I want to pass into appendFormat(), will all just get passed to String.format() and the whole thing is much nicer then when I started.


ScottCate.StringBuilder = function(len) {
    ScottCate.StringBuilder.initializeBase(this, [len]);
ScottCate.StringBuilder.prototype = {
    appendFormat: function(mask) {
        this.append(String.format.apply(null, arguments));
    toString: function(delimeter) {
        return ScottCate.StringBuilder.callBaseMethod(this, 
"toString", [delimeter]); } }
ScottCate.StringBuilder.prototype = { appendFormat: function(mask, arg0, arg1, arg2, arg3,
arg4, arg5, arg6, arg7, arg8, arg9) { this.append(String.format(mask, arg0, arg1, arg2, arg3, arg4,
arg5, arg6, arg7, arg8, arg9)); }, toString: function(delimeter) { return ScottCate.StringBuilder.callBaseMethod(this,
"toString", [delimeter]); } }
ScottCate.StringBuilder.inheritsFrom(Sys.StringBuilder); ScottCate.StringBuilder.registerClass('ScottCate.StringBuilder',
Sys.StringBuilder); function TestSB() { var sb = new ScottCate.StringBuilder(); var mask = "{0} goes in front of {1}"; sb.appendFormat(mask, "This", "that"); alert(sb.toString()); }

[UPDATE2 2008 Sep 05] I've had two different code versions of this for a while, and the second prototype version of this is now posted online.


Palermo4 said:


Great blog post.  Just thought I could add one other simple observation.  You don't even need the "mask" argument for your appendFormat to work.  Just specify function() and it will still work.

# January 24, 2008 11:27 PM