Thursday, May 26, 2016

An Angular 2 Master/Detail using JavaScript

In this post, I'll talk about a complete Master/Detail sample I created for Angular 2 using JavaScript.

UPDATE 7/22/16: Fixed breaking changes in Angular with file refs.

[VIEW THE Plunker]

Why a JavaScript Sample?

It is apparent that TypeScript is the language of choice for Angular 2, and with good reason. But when teaching Angular 2 concepts to someone for the first time, it can be a benefit to stick with JavaScript, thereby removing the confusion of new TypeScript constructs. Not surprisingly, there is a dearth of full examples using JavaScript in Angular 2, so maybe this sample can help fill that void.

Using the Sample with MVC Web API

This sample was originally created with the Service hitting a Web API, but was adjusted to use an in-memory array for Plunker. The following tweaks are needed for hitting a Web API:

In beers.service.js, change the CRUD methods to use appropriate ng.http methods, and point to the MVC Web API url. Note how we add the ng.http.Headers collection as a parameter to the post call. This is important to avoid an error "415 / Unsupported Media Type: No MediaTypeFormatter is available to read an object of type 'xxx' from content with media type 'text/plain'."

        getBeers: function () {
             return this.http.get("api/beers").map(
                 function (res) {
                     res = res.json();
                     return res;

         saveBeer: function (beer) {
             var headers = new ng.http.Headers();
             headers.append('Content-Type', 'application/json');
             return"api/beers", JSON.stringify(beer), { headers: headers });

         deleteBeer: function (beer) {
             return this.http.delete("api/beers/" + beer.BeerId);


In beer-master.component and beer-detail.component, the promise will now be an observable, so we instead use subscribe to await the return:

                 function (data) {
                     self.beers = data;
                 function (err) {
                     self.error = err;


The Web API Controller itself should look something like the following.

    public class BeersController : ApiController

        static Dictionary<int, Beer> beers = new Dictionary<int, Beer>()
            { 1, new Beer { BeerId = 1, BeerName = "X Double Indian Pale Ale", BreweryId = 1, AlcoholPercent = 10.0M, ImageUrl = "" }}

            // ... add more beers here :)


        public IEnumerable<Beer> GetAllBeers()
            return beers.Values.OrderBy(b => b.BeerId).ToList();

        public IHttpActionResult GetBeer(int id)
            var beer = beers.FirstOrDefault((p) => p.Key == id);
            if (beer.Value == null)
                return NotFound();
            return Ok(beer);

        // POST api/values
        public IHttpActionResult Post(Beer beer)
            if (beer.BeerId == 0)
                // new beer
                beer.BeerId = beers.Max(b => b.Value.BeerId) + 1;
                beers.Add(beer.BeerId, beer);
                var beerEdit = beers.Where(b => b.Key == beer.BeerId).First().Value;
                beerEdit.BeerName = beer.BeerName;
                beerEdit.ImageUrl = beer.ImageUrl;
                beerEdit.AlcoholPercent = beer.AlcoholPercent;
            return Ok(beer);

        // DELETE api/values/5
        public IHttpActionResult Delete(int id)
            return Ok(id);


1 comment:

  1. Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a Front end developer learn from TypeScript Training in Chennai . or learn thru Javascript Online Training from India. Nowadays JavaScript has tons of job opportunities on various vertical industry. ES6 Training in Chennai