JavaScript: remove leading and trailing spaces

Ramble Preamble

Hot on the heels of finishing off one of my non-JavaScript mini projects – the reason why there’s a lull of late on this blog – I’d come to the weary conclusion that somethings you just need JavaScript for. The project in question is a web port of a simple csv convertor desktop app built with python and tkinter.

The web version was done using flask – a python based micro web framework. Most of the logic required was done with the desktop version, which was just simply transferred to the server side code and worked without a hitch. The snag was that the user input had to be sent via a HTTP POST message that would be picked up by the flask routing system, processed and then sent back, not ideal in of itself but stuck with it as I couldn’t find any alternative. The problem was that the post message had a size limit and thereby dropped anything over 1567 rows…

…what can be done in the browser should be done in the browser.

Enter the JavaScript

Realisation slowly dawned that JavaScript is needed, as what can be done in the browser should be done in the browser. Everything was fine until I found out that JavaScript was limited in terms of being able to trim leading or trailing spaces, or so I thought.

A quick search of something similar to Python’s lstrip or rstrip brings up several articles which talk about either using the trim() function introduced with ES5 (ECMAScript 5), extending it using the prototype chain or, prior to that, just crafting your own function using regex expressions.

It just so happens that there are native functions built in that accomplish what I need –

String.trimStart() – Remove trailing spaces from the start

String.trimEnd() – Remove trailing spaces from the end

It’s great for removing any and all trailing white space, including new lines which was causing  trouble with my output. However, unlike their counterparts in Python, these functions do not allow passing any character inputs as filters. For e.g. in python, specific characters such as trailing commas or formatting tags like carriage returns or new lines can be passed for removal

Convert to CSV

In my case my code would append a space followed by a comma ” ,” to the end of each row input. This presents a trailing comma which the Python rstrip would take care of in one swoop, of the fell kind. However, thanks to finding the trimEnd() method, the solution that presents itself is very simple if not crude. Come of think of it, I could have easily solved the problem of trailing space with just the trim() function. Anyway here’s the sols:

After having to troubleshoot why my slice wasn’t working as it should – there was still trailing white space – I came to the sobering relisation that the split function does in fact split everything into a new comma separated list (doh). Anyway the extra formatting on line 10, as it was renamed to later on, does exactly that now, but wasn’t needed. Ah well, hindsight is 1 they say…which is what I calculated 20/20 to be – true.

So here’s to polishing off this project with just the bare minimum functionality for the moment, which is convert to CSV.

AngularJS To do App – Part IV

Following from the previous entry, there was just one feature remaining for the rudimentary functionalities of our app:

  • Check of an item

I added an input checkbox to the ngRepeat construct. And after some fumbling around and going through some forums + angularjs developer documentation, I managed to apply a simple class styling to the item in the list when the checkbox is checked.

// Class applied when model ticked is true
<input type="checkbox" name="tickbox" ng-model="ticked" />
<span ng-class="{'checked': ticked}"> {{ item }} </span>

// CSS style that's applied
.checked {
color: gainsboro;

This accomplishes a somewhat crude implementation of a To Do list item being checked off. However, the styling seems to fall through to the next item when a checked item is deleted. Also a checked item should preferably be locked from being edited.

So that still needs to be worked on and possibly some extra refactoring of the code in terms of button states as extra conditions required to prevent the fall through will only add to the growing list of conditions on some of the buttons already:

<button type="submit" ng-show="updateShow" ng-click="update($index, editedItem); updateShow= false; showEditInput = false; editShow = true;">Update</button>

Apart from that some aesthetic tweaks to the design and form is warranted. So stay tuned and check out the latest:

App – To Do | Commit

AngularJS To do App – Part III

So out of the remaining features, what should I pick next to work on, hmm let me see. Edit an item, sure why not. Why not indeed.

  • Check of an item
  • Edit an item
  • Delete an item

It turned out more difficult than I had (not) anticipated. Not the most crucial feature but sure. Thought it would take a few days to figure out and slow down development as I couldn’t find much of a guide from scouring through a book or two and several forums.

Thought there might be some directive floating around I could use (didn’t find anything remotely close). Then I tried to do a simple update the array item in place technique.

But therein lay the difficulty as threading it through AngularJS wasn’t easy going. I cycled through a few ways to do it. Some of it involved  a straight ngClick using the $index as a parameter which would try and update the array item based on that index.

That didn’t work as the button I wired up to do the ‘in place’ editing simply cleared the value already present and just left the input field and buttons showing:

$scope.update = function(index){
  $scope.items[index] = $scope.item;

Or something along those lines as I’d changed code and banged my head so many times I can’t quite remember.

It did work eventually by recreating the first pattern I had for adding an item into the list – I needed to create a new model on the fly using ngModel and then passing the $index and that model to the function call within the controller code. Still peculiar how I couldn’t get it to work by referring to the newly created model from the $scope variable.

In hindsight the solution I came up with is very very simple and it works. The condition updating to show/hide buttons for editing purposes is verbose. Hopefully find a more succinct system or pattern online later for refactoring but for now it does the trick.

So now just one primary function left to complete to call it a mvp

  • Check of an item

For now here’s the updated demo To Do App & the latest commit.

AngularJS To do App – Part III

So continuing on and upwards, what every To do list should have, in no particular order are the following:

  • Check of an item
  • Edit an item
  • Delete an item

Incidentally the first thing that came to mind was the delete function (only when I had that did the rest occur, which arguably are more important features).

I somewhat implemented deleting by including a  button with a ngClick directive within the ngRepeat directive:

$scope.del = function() { $scope.items.pop(); }
<ul ng-repeat="items in items track by $index">
<li>{{ item }} <button type="submit" ng-click="del()">X</button></li>

Sure, it should only affect the item it is (magically) tied to heh, heh… no. Pop didn’t go the weasel as it removes an array item from the end. And any other array method I’d come across didn’t seem to be able to remove items unless at the start or end. However, in that same post I had linked to ECMA-262 (Standards Document) which is the comprehensive language specification guide for ECMAScript, or JavaScript as its known as when not protecting Gotham city. That had fairly detailed (verbose) items about array methods – in particular Array.prototype.splice. I thought it was like slice but it seems similar to what a delete function should do:

Array.prototype.splice (start, deleteCount, ...items )
Note:  When the splice method is called with two or more arguments, start, 
deleteCount and zero or more items, the deleteCount elements of the array 
starting at integer index start are replaced by the arguments items. 
An Array object containing the deleted elements (if any) is returned.

Sounds about right, except I don’t want to want to replace anything with something else, nor return the deleted item. The language specification document is not the most user friendliest nor have any usable examples, but there’s tons of other information available on splice online. states that the splice method adds AND removes items (holy utility belt stuffer Batman). Also it clearly states that second and third parameters are optional.

So our delete function is pretty similar to the add function:

$scope.del = function(index) { // parameter for index
  // start at index required and delete one item, which is itself
  $scope.items.splice(index, 1);

So in our HTML, we just need to just latch onto current index position of the item to which the delete button (with the ngClick directive which is iteratively assigned by ngRepeat) is attached.

Being the cool cat I am, I intuitively (counter it seems in hindsight) just threw in ‘this’ into the delete function as a parameter"del(this)">...

Because this is all powerful, this is better than that (except when you assign this to that). I should’ve known better than that – what I did was a total party foul, which I won’t get into at this moment. At that stage the list item was being removed from the top, like shift() would. The proper solution, it turns out, was staring at me all along.

I ran into the issue of not being able to create more than one item in the list, mentioned in the previous post, because AngularJS doesn’t like duplicates in the ngRepeat directive. The fix was add ‘track by $index’ – which assigns, and I quote, “each list item a key by virtue of its index…”

So now each added item has its own delete button which only applies to that item.

All the updates can be seen in the latest commit.
Updated functionality can be seen on the associated github page ‘ToDo’. (might need to do a hard refresh to get the latest working example).

More on the other features coming shortly…

ps I renamed my html file from ‘todo.html’ to ‘index.html’ which shows up in github diff as two different pages.

AngularJS To do App – Part II

When we last left, our intrepid developer in the making, he had had completed the shell and basic setup of his AngularJS app. Lets see what he’s upto this week…

The To do list has so far taken shape and the basic structure and logic was coded. However adding an item presented two issues:

  1.  We couldn’t add more than one item
  2.  The added item was bound to the new input field

Issue ‘1’ turned out to be Angular pointing out that the ngRepeat directive does not allow duplicates – the message could be seen in the console.

Angular error: Duplicates in repeater are not allowed.

This happens when there are duplicate keys in an ngRepeat expression. Also not having any key implies all items have the same key – food for thought. The resolution is adding  ‘track by $index’ to the ngRepeat attribute value

ng-repeat="item in item track by $index"

This assigns each list item a key by virtue of its index where there is no explicit key defined. This fixes issue ‘1’ and more items can be added to the model, however all of those added items are all bound together and in turn to the input box. So every time the value is updated, all instances are updated as well. [see commit]

After scouring the interwebs for a bit and running through a few related but not similar issues on stackoverflow and old old tutorials, I tried a few things

  • Changing the array of objects to just an array of strings [not much different but when you’re going crazy and it’s nearly bed time might as well]
  • Tried using different versions of angular [static library was used, an old version 1.2.16, then the latest and something in between]

Finally what worked was not passing in the new object created using the ngModel directive as a parameter in the ngClick directive on the button and then getting the object from the $scope directly within the add function call.


<input type=text>
<button type=submit ng-click=add(new)>Add</button>$scope.add = function(item){


<input type=text ng-model=new/>
<button type=submit ng-click=add()>Add</button>$scope.add = function(){

Not entirely certain why it was fixed, but assuming that somehow accessing the object from the $scope ensures that each one is separate from the others and doesn’t end up being tied to the same instance as before.

For now it’s doing another aspect of what we intended to do – adding items to the list correctly without duplication.

I’ve pushed the changes [see commit] and added a github page to see it in action – To Do App


Hoisting in JavaScript

Everyone’s heard the all too familiar, JavaScript is an interpreted language spiel. That’s only partly true. Certain instances  can catch unwary developers out about this idiosyncratic run-time behaviour.

When a JavaScript engine parses a code file, a global execution environment called the execution context is created. This occurs before the file is executed where functions, variables etcetera are ‘hoisted’ into memory. Think of this as instantiation in other languages.

Hoisting is what allows function calls, which occur before the function definition, to run without throwing an error – as the entire function will be hoisted to memory.

This causes issues where function expressions are used. Function expressions are anonymous functions which are assigned to a variable as opposed to a function statement:

// Function Statement
function doSomething(){
   console.log("something done");

// Calling 

// Function Expression
var functionHolder = function() {
   console.log("doing something else");

In this case the variable functionHolder will be hoisted into memory, however it will be ‘undefined’ until the interpreter reaches the actual line where the anonymous function is assigned. At this instance a function object is created and assigned to the variable functionHolder.

For more details about functions expressions, see:
the official description on MDN
JavaScript functions
JavaScript callback functions

JSON and JavaScript Objects

JavaScript Object Notation (JSON) is the lightweight alternative to tag laden XML used as data exchange format. What it is, precisely, is a method of data transmission based on JavaScript’s object literal syntax.

JavaScript objects are containers which store key value pairs of attributes, functions and other objects of the following appearance:

var anObject = {
 firstProperty: 'someString',
 secondProperty: 111,
 aFunc: (parameter) {
         // some code
 isJSON: false

JSON follows the same exact pattern:

  "firstProp": "someString",
  "secondProp": 222,
  "isJSON": true

Few items of note that distinguish between JSON and plain old JavaScript objects:

  • JSON requires that properties by enclosed in quotes, while JS Objects can do it either way.
  • JSON only contains key value pairs, no functions

Back and forth

Although not part of the language, its ubiquity means that JavaScript has helper methods to handle JSON. Most common function is to convert from an object literal to JSON and vice versa:

// Object literal to JSON
var myObject = {
   firstProp: "someString",
   secondProp: 222

var JSONresult = JSON.stringify(myObject); 
// Result
//  {"firstProp": "someString", "secondProp": 222 }

// JSON to Object literal 
// result
// { firstProp: "someString", secondProp: 222 }

So although similar, JS objects and JSON are not the same. In essence JS objects is how you might be normally at home, relaxed and casual versus while JSON is like being in public with more formalised rules.

HTML5 enhancements

Now it’s been some time since HTML5 came on the scene. It’s shiny new glean has been replaced with a well worn veneration and stability.

Although it’s made some marked improvements over its predecessors in terms of not requiring laboured attributes or overly strict syntax, one of its tenets means a certain level of backward compatibility still exists. And owing to the certain habits or strict requirements in the past, some developers simply would’ve stuck to those habits or not realised that with the latest iteration, that some items were no longer needed. This lists the obvious, and not so obvious items.


This is the most obvious one and one which is required. So, without delving into all the iterations and variances, the last two major branches, XHTML and HTML 4 series required a lengthy declaration of the schemas used for the document type defintion (DTD). HTML5 did away with all the cumbersome description and replaced it with the all too popular and well received

 <!DOCTYPE html>

Linking to external files

A CSS style sheet is referenced in an HTML file by using the <link> tag, while JavaScript is referenced via a src attribute in a <script> tag. Where the JavaScript reference required an attribute to specify it was of type ‘text/javascript’, and similarly with CSS being ‘text/css’, is no longer required.

<script src="js/script.js" type="text/javascript"></script>


HTML5 enables asynchronous loading of scripts without locking the other processes from loading in a browser. This is done by using the async tag

<sript src="js/script.js" async></script>

How? By using the async attribute preventing users from having to worry about script link placement and all the consequences the decision imbues.


Defer is similar to the Async attribute, however, it can be used when multiple scripts are needed and should be loaded in order. Scripts with this attribute will wait to execute until the page has finished loading.

These are some of the enhancements for the moment. If there are ones that I have missed, especially major ones, let me know in the comments.

Get started using web API’s – Luas Forecasting API Part Three

After much struggles, see the previous entry for the history up til now, the responseText message was successfully parsed and the information populated on the page:

Luas Arrival Time

Luas Test App

Some of the pitfalls:

  • Response message was a string which wouldn’t yield to any XML extraction methods. That was sorted once parsed to XML. (Response methods for XML didn’t yield anything or issues further along made me dismiss it altogether.
  • It was impossible to extract any data, attempts yielded
    • XML Object Element.
    • HTML Object Element.
    • Null.
  • Xpath was used to get at the data but still no luck (some remnants can be seen as code or comments).
  • API was down for maintenance which didn’t allow much progress.

There were myriad of explanations and convoluted methods to get the data but the issue lay in that the information needed was in the attritbutes and not in the nodes. I’ll do a clearer, indepth write up of all the steps taken to create this but for now this shall be parked.

Some improvements I’m planning on however include:

  • Automatic updating of the page when the response refreshes.
  • Selecting stops by name and whether inbound or outbound.

Stay tuned for that and more!