This blog attempts to be a collection of how-to examples in the Microsoft software stack - things that may take forever to find out, especially for the beginner. I see it as my way to return something to the Microsoft community in exchange for what I learned from it.

05 August 2014

Intro – multiple stacks to choose from

There are a number of ways to talk to a backend (i.e. communicate over JSON services) in Angular. I know at least of two built-in: the $http api, which basically gives you a bit raw, jQuery-like API, and the $resource API, which kind of builts on top of that, using a more formalized approach. Also, you can choose to forego the whole built-in stack and use something like Breezejs which has it own pros and cons. I used both successfully. And I don’t doubt there are more. But in this article I will concentrate on $resource.

Once again, I don’t claim ultimate wisdom nor do I claim this is the best way, but I describe a way that works and is complete.

Setting up the backend

I continue where I left off in my previous post, and proceed to add a model class in the Models folder. Mind you, this the folder in the root, not that in the app folder with TypeScript stuff in it. We are talking C#. Our application will be extended to maintain a list of phones.

Then add a WebApi controller in the Controllers folder. I right-clicked the Controllers folder, clicked “Add/Controller”, selected “Web API 2 Controller with read/write actions” and called it – very originally – “PhonesController”. I implemented only the Get and the Post method, to prove the communication actually works:

As you can see this implements an ‘in memory database’ ;-) to list and store phones. To make sure WebApi honors the JavaScript convention of using camel casing, the following code needs to be added at the end of the Register method of the WebApi class in App_Start:

The last statement is actually only to make WebApi default output JSON – this is not actually necessary, but it makes testing WebApi a bit easier. To get this to work, three extra usings will be necessary:

using System.Net.Http.Formatting;
using Newtonsoft.Json.Serialization;
using System.Net.Http.Headers;

This is easiest in Chrome, as it has no qualms about displaying raw JSON in the browser. In Internet Explorer it works as well, but IE insist on saving the file to disk, refusing it to display for security reasons. The backend now works.

Which gives a nice skeleton that we can use. I don't like client side models sitting next to C# code, so I create a folder "models" in my "app" folder and moved this file over to that location (for some reason that does not work in the Solution Explorer; I used the Windows Explorer to do that). I addition, I renamed the file to Phone.cs, made a class of it and put the class inside the App.Models namespace, so the net result is:

Now this is where is gets a little complicated and it had me reeling some time. If you want to use a resource to get models from and to a backend, you will need to define a resource on an interface, not on a class. According to this Stack Overflow example – the only one I have been able to find, although it is parroted on several other places (up to and including the errors that were – and still are – in it) – we need two interfaces like this:

Then we define a simple interface that only extends a resource on IPhone. I define these in the “resources” folder (and namespace) as I like to keep related stuff together. First, I define a resource definition interface

Now you can still reference to an IPhone object and have a concrete implementation of it and have a resource. As you can see, having type safety comes at a price. Remember that interfaces in JavaScript don’t exist and that this code won’t translate to any JavaScript code. All you are basically doing is providing scaffolding for type checking at compile time. Pure JavaScript fans will say they can write a lot more with a lot less code. I think they are right. I assume rock star programmers with an IQ of 200 can also go a lot faster if they don’t write unit tests for .NET code as well. The rest of us, the mere mortals, need all the help we can get.

Adding a resource builder

Now this may also seem like a lot of overkill, but believe me – when you start adding more and more resources to your app, you will se a lot of repetitive code in your AppBuilder. Me se not like that, to quote a beloved ;-) Star Wars character. So I came up with this Factory to build services for me:

Not really rocket science here – a method to load phones from the server using the resource “query” method, and a method to save a phone using the resource “save” method. By inheriting ng.resource.IResourceClass we got all this methods for free, in stead of that we had to implement that all by ourselves using the $http stack.

Interlude - ways to mess up TypeScript callbacks"I have not failed. I've just found 10,000 ways that won't work" - Thomas A. Edison

Sometimes you make typos, or honest mistakes. TypeScript, although being very powerful, has, like every other programming language, it’s own unique set of particular devious pitfalls that sometimes makes you wonder if someone made them on purpose. Observe way the callback is called:

This will compile, and saveCallBack will even be called. Only you will notice you have lost the "this" inside saveCallback. Ain’t life fun sometimes? Please take care when making callbacks. Don't fall into the same traps I did.

Conclusion

This took me quite some time to figure out, and I am not one to sing my own praise but this may just be the only complete – and running – sample of using Angularjs resources with TypeScript. Most of what I wrote here is out there somewhere on the web, in bits and pieces, and sometimes partially wrong. Anyway. This works. Running sample solution, as always, can be downloaded here.

Now my only hope is that I won’t get sued over violating some copyright rules by defining a TypeScript interface whose name resembles a popular brand of phones made by a company whose name resembles a common fruit ;-)

Feedback, comments and tokens of appreciation

If you spot things that are incorrect, or if you don't understand what I mean, please drop a comment on the offending article and I will help you ASAP. You can e-mail me at joostvanschaik at outlook dot com or contact me via twitter.

If you find the information on this blog useful (and apparently some 600+ people per day do on average) please let me know as well, that encourages me to keep doing this. Or do tell others - that made me an MVP; who knows what more it might bring ;-P

Disclaimer and legal stuff

Although I take great care in providing quality samples, all postings, articles and/or files on this site are provided "AS IS" with no warranties, and confer no rights. The views expressed on this blog are strictly my own and do not necessarily reflect the views of my employer, or anyone else on the planet for that matter.

I usually make original content, sometimes building upon other people's work. Sometimes I explain things that can be found elsewhere because I felt what I read was not clear enough for my limited mind so I explain it the way it finally clicked with me. In all cases I take great pains to be sure to link to people or articles who deserve the credit. If you think I have shortchanged you on the credits please let me know.

Please note, I do not work for Microsoft and while I proudly wear the title of "Microsoft Most Valueable Professional", my opinions, files offered, etc. do not represent, are approved of, endorsed by or paid for by Microsoft. The only power behind it is me and my sometimes runaway passion for parts of Microsoft's technology.