Share data between controllers in AngularJS

I have situation where it seemed useful to have data shared between two controllers. First controller is just a list of elements. Second is edit controller to adjust values of elements. I could have just loaded this single element back from server and it would be fine and probably pretty fast as well. But why, I have all the data I need just here. Why cannot I use it? Well – sure I can, I can go with shared variable, as was my initial idea:

Code is pretty straightforward: module definition with routing, two controllers: list one, that gets the data and edit one – which just picks the data from already downloaded values.

Have you coded for few months even, I bet you heard that global variables are no good. And sure they are, global state is always hard to manage. So can we do something with this? AngularJs have two great things that will help us solve this issue: incjector and factories. You can look through their documentation, but put simply: you can define some factories in module and then use parameters named like those factories and injector will automatically fill those parameters for you. Simple, classy, easy to code. Just look:

A bit more code there, but still easy to understand, don’t you think? We declare factory on module, named contentProvider and then we use parameter with the same name in controller’s constructor – Angular will put the instance returned from factory there for us.

But wait, that won’t work – factory will return new value each time, right? Well, no – Angular is clever enough to limit instance just to one and reuse it each time. Our list will get the data and edit will have it ready when needed.

Can you see the issue here? The most obvious one, for me, is that if we tried going directly to /edit/1 page for example it will fail – we skipped list page so the data was never downloaded. But I’m sure we can do something about that and it will be fairly easy. Angular will do its best to assist us.

Advertisements

AngularJS for web UI?

Well, yes. AngularJS. Why not? It got a lot of attention recently (or maybe I just noticed that) and it seemed like a good idea to try something new after having most of my .NET web experience with ASP.NET WebForms (and you don’t want to go that way if you don’t need to). So I picked it and started having fun.

And fun it was, indeed. Pretty simple to start and create something. Nicely working, updating UI form model, updating model from UI. Clean code, clean HTML markup. I must say I’m impressed, didn’t expect it to be that easy and nice (the same feeling I had with NancyFX recently, I start to see a pattern – I’m doing what I want, how I want and with tools I want – me like it).

But there are some dark corners in Angular that got me when I least expected it. First – double declared ng-app attribute. Well, my fault of course. I set it on html element first in Master Page, done few things, changed few things and added by mistake second ng-app attribute in actual page, using this master page. Small error, but application stopped working, nothing behaved like expected. Blank screen, no bindings. Took me quite a while to figure it out. Oh, how I wish Angular told me – hey, man. I’ve noticed you put two ng-app attributes in your page. Sure you wanted to do that? But nope, nothing, zero, nada.

Second time it bite me was when I was doing some model data manipulation. Everything working fine in JavaScript, but in UI – nothing gets refreshed. I used ng-click binding to get function executed. Oh, how much time I spent (but not wasted completely) looking for error. Everything seemed to be ok, code works, just UI isn’t right. Looked at documentation, looked at StackOverflow, looked at blogs. Nothing helped. Learned a lot about Angular, but I just wanted my bindings to work! Well, look at this code:
<a href="#/" ng-click="manipulate()">Link</a>
Nothing extremely complicated. What’s wrong? It have href attribute set. Oh boy, I had nice facepalm once I noticed it. With Angular routing set up, going to #/ caused re-creation of my controller, reloading data and refreshing page. But it all happened so fast that I simply did not noticed and it all looked to me like my code is not working. Remove href and guess what? It was working like a charm from the beginning.

I’m pretty sure I will have quite a few problems with Angular. But it seems to be such a great tool that I am willing to solve them and learn along the way just for fun of working with something that clever.