Pain and suffering with AngularJS

What a week!

Over the last month or so I have been steadily learning Javascript, Bootstrap, NodeJS and AngularJS well last week added to that mix was D3JS. I must have got to the end of my tether every day last week. I’m pretty sure I was suffering from information overload and before going any further I will say D3JS is really powerful and looks to be a tool I’d like to learn to use, the only downside is even after a week of drawing circles, bar charts and trying line graphs I am still struggling, but hopefully my struggling has not been in vein I learn some good things and if I’d known them before I’d started a lot less pain and suffering would have ensued.

The problems

So I don’t know angular, I also really struggle to read large chunks of text like the APIs, I did do the tutorial which helps but not really… There were a number of issues, not knowing how angular worked interms of where the right place to put things was a big set back, not knowing how to get data between the various components and updated was another. Another area of challenge was the asynchronous nature of Angular, making a $http.get request and not having data available instantly is odd but easily over come once you know how.

In importance order…

Callbacks

A long while a go I wrote a blog called What University forgot to mention about programming, it turns out this was one of those things that would have been really useful to be learning if the course wasn’t dumbed down to cater for those that didn’t come from an IT background at college.

In short I was doing this:

var data = [];

function getData(){
  $http.get('/api/data').success(function(response) {
    data = response;
  });
}
getData();
alert("data is 0!? " + data.length);

The problem with this is that getData is called and initiates the $http.get which does not return data, it returns the promise of having data; When it actually gets a response it moves on to the function declared in then(). Remember the way Javascript works is we passed in that function as an Object which then gets run when the data returns, it passes in the response for us to then handle. Because $http.get returns a promise that function is done, everything executed, the anonymous function we declared is a parameter that has been forked in the browser or language somewhere and is running isolated from everything else.

The way around this is to structure code in a way that allows for the callback to then do what you needed so….

function getData(cb) {
  $http.get('/api/data').success(function(response){
    cb(response);
  })
}

function drawGraph(newData) {
  //some code to draw a graph omitted...
}

//Draw a graph
getData(drawGraph);

By using the above method you only draw the graph when there is data, take this; rinse and repeat and all will be well, except this method is only really good for a one time graph. Controllers only get called once, they can be used to set up functions to be used in the view etc but they are ultimately only run once.

Data Binding

Firstly, read about Data binding. This first mistake I made was trying to do everything in a controller, it’s the most natural as everything in there gets run like when you include a normal js file, but it just makes life harder than it needs to be.

Originally I was doing something like this:

function getData(cb) {
  $http.get('/api/data').success(function(response){
     cb(resp);
  });
}

function updateData(data){
  drawGraph(data);
}

function drawGraph(data){
  //some code to draw a graph omitted...
  getData(updateData);
}

//Draws initial graph and then kicks off an infinite loop of getting data/drawing graphs 
getData(drawGraph);

I was using this to update and draw a graph. This works sort of but I was not able to get it to work because of my understanding of D3Js at the time, I’m sure smarter people than I could make it work but that’s not how it should be done; theres a better way like explained in the link above about data binding.

If you take your partial (template) and put certain triggers in it, even manual like ng-click you can do this a lot simpler, you can even use $watch to continuously update. so if you were to define a function or two like this…

In your controller:

$scope.updateGraph = function() {
  getData(reDrawGraph);
}

function reDrawGraph() {
  //code to RE-DRAW not draw the graph
  //Enter new, Transition, exit... more later...
}

In your partial:

<button class="btn btn-success" ng-click="updateGraph()">

You can make it update as you go. One step further would be to use $scope.data and just have a loop in the controller that sets that when data comes back, combined with a $watch to always re-draw.

Directives

Okay, so directives are useful, Until I learnt about them I was drawing all of my graphs from the controller and by far the must successful graphs I did were all in the directives area. I still think there was a better way because I was struggling to get it to work with $watch either way by having this layer you achieve two things, less crap in the controllers, and a nice location to do the DOM manipulation, which for graph drawing is kind of handy. Because this links right in with the html it is easier to manipulate.

Summary

These are just some of the major hurdles I overcame while trying to get D3JS working, and there’s more to come when I get on to D3JS which I have to admit I only got basic graphs drawn but I do think it’s an area worthy of diving into with more detail. All in all these experiences have made my understanding of Angular a lot better I am now able to quickly and easily make changes to pages to do basic things like looping through JSON data to display lists of data or forms to submit data.

When in doubt, use more JavaScript

Oh, gawd, why

Over the last couple of weeks i’ve been playing with some new technology, not to any depth but just enough to get a feel for it. The week before last it was all Python & Django followed by AngularJS, well this week has been a bit more Javascript in the form of Node.js; granted I’ve not done much but I’ve done some.

As always it started in a random planning session where we have decided that we will make our own tool that will replace our current monitoring tools, the architecture was all drawn up, queue services, agents, plugins, a super fast “worker” process for handling the queue and a management console for pushing commands in and displaying results.

Because of my last two blog posts I got volunteered to do the front end, which is good as I will learn more AngularJS which I would like and I will learn more bootstrap which I would like, I also thought I’d get to write a nice backend in the language of my choice; turns out, not so much.

Would it be Ruby now I’m getting proficient with it? maybe Python, the rest is in Python, I could live with python, it’s not too dissimilar to ruby. It turns out it would be in node.js, oh gawd why. I’m not a fan of JavaScript, and here’s why; back in the day for my university final year project, back when AJAX had just come out and there were no libraries to do it I made a GeoBlog, using google maps API’s, JavaScript and PHP. It had over 1000 lines of javascript, there were no debuggers, the best you had was a console to point out syntax errors. Well that was a nightmare, at least now things have improved with proper debuggers in the browser etc etc so this time would be better…

Sort of…

To be honest node.js isn’t that bad to write simple things in, I’ve been getting more confused by having controllers and routes for both angular and node and trying to keep that separation in my head. I’ve so far been keeping good to my promise to do button first development so other than writing a simple api to return json I’ve not had to do much in node yet and only a little angular but at some point i’m going to get really stuck.

For some reason all these moving parts haven’t yet fallen into place and I’m wondering if I need to go back to some basics and re-vist javascript in it’s pure form and start building on that to get int node and angular. At the moment my coding is purely google, copy, paste, edit; not much in the way of understanding and if I’m going to make this thing work I need more of an understanding.

Maybe I should start with my old friend w3schools followed by some Code Academy followed by all of these

Busy week ahead I think, wonder if it will help or confuse me more, either way more updates next week I think :)

Angular.js – starting something new

Why not!?

Last week I played with Python / Django the natural extension of this was to not do python but to look at using something like Angular and bootstrap, the main reason for this is that just using python / django gives you server side manipulation but why do it all on the server? Ideally the server would generate relavent data and sent the data back to the client for processing, this is how the internet is meant to work after all. Think about simple HTML and CSS, HTML is just a data structure and CSS formats that to make it look pretty for you, now, with modern computers being so powerful, why not have it do the formatting in CSS and also manipulate the data into the right structure.
This way the server just generates a response of say JSON and the client takes this and manipulates it into tables / lists or what ever you need. Another advantage to this approach is all of a sudden you have an ajax driven website with not too much effort which is more efficient on bandwidth, combined with local client side caching of information the user experience should be pretty quick and seamless with or with ut the server, as long a sit pulls the dat to start with it should be okay.

So that covers why Angular, Bootstrap on the other hand is more or less just CSS but quite frankly, I can’t do CSS it never looks right so by using bootstrap I can then programatically set out hierarchy and classes etc while leaving the pretty styling to a theme generator Like this or download one Like this

Tasklist

Okay this is not really fully featured.. You can’t delete stuff from the list it just gets bigger and bigger but was only done to use the combination of applications in the right way and see if it worked, well it works, you can add tasks and it displays them so lets have a look at how pretty it is:

TaskList home

I was only able to achieve this level of prettyness because of bootstrap my past sites have all looked terrible…
The home page just includes some example code from the AngularJS website to prove I managed to get Angular working before butchering it with my typos.

Here’s a picture of it listing the tasks…

TaskList list page

So for starters if you’d like to criticise the code the best way of doing that is on GitHub I have no intention of making it any better but if you want to play with Angular, Mongo, Python and Django where python/Django provides a rest api to the DB and Bootsrap/AngularJS provides the front end then this has it all and the set up is pretty straight forward and some brief notes on install / settings in the README. Maybe you could add the ability to edit or delete tasks maybe put a checkbox next to them and track a done status who knows…

Overall…

I quite like Angular and bootstrap as a combo, I think it’s got some real potential to do some powerful stuff and i’m sure people out there are doing some really crazy things with it, hopefully one day that will be me and there will be something worth while coming out of it. I’m not convinced on python/django combination, I’m sure it’s okay but I really need to write some more of it and see how it goes; I’m fairly sure it’ll be better than RoR but that’s not a good framework for ruby anyway.

My next task having played with those is to do something even more whacky, maybe some sort of node.js backend, angular boot strap front end and some sort of queue… The next project I’m working on with a larger team will be pretty good and once we have something up and working it can be shared, the oddest thing will be the “button driven development” approach to development, which is basically top down, where you prototype the interface to look as you want it to and then fill the data with dummy values or hard coded values. Once that’s done write a backend that provides the data. In theory by the time you get to do the technical nitty gritty there’s a very clear idea on what the output should be.