Ionic Framework Inside a Visual Studio Cordova Application using Typescript Part 3

Part 1 – Tools and a first glance
Part 2 – Ionic meets Visual Studio
Part 3 – Enter Typescript

In part 2 we made the ionic application run inside Visual Studio. Now how about

Adding Typescript

 

We want more meaningful detail pages when navigating to the … well, detail page of a playlist. What happens when we click on a playlist inside the playlists list?

  1. App navigates to the new href, in this case /playlists/<playlistId>
  2. UI-Router compares that against its route repository and selects the matching route (called app.single)
  3. It then activates the corresponding controller (PlaylistCtrl) and makes the id of the selected playlist available as $stateparams.playlistId

Have a look at app.js to see the router definitions.

Hmm – so we’re only getting the id of the playlist? But we need to have the full object! What’s the best practice to pass data around in AngularJS? Services! Right.

Currently, we’re creating a bit of dummy data directly inside PlaylistsController (plural, master view).


.controller('PlaylistsCtrl', function($scope) {
    $scope.playlists = [
        { title: 'Reggae', id: 1 },
        { title: 'Chill', id: 2 },
        { title: 'Dubstep', id: 3 },
        { title: 'Indie', id: 4 },
        { title: 'Rap', id: 5 },
        { title: 'Cowbell', id: 6 }
    ];
})

We need to refactor that into a service if we want to access these objects inside PlaylistCtrl (singular, detail view). We need to create a new Typescript file called services.ts inside /scripts/app.

Optional, but good stuff: To get Intellisense support (one of the benefits of working with Typescript), right click on angular.js inside /scripts folder and hit “Search for Typescript Typings”. In the list that NuGet Manager shows, select angularjs.TypeScript.DefinitelyTyped and click Install. This will include a set of *.d.ts files inside /scripts/typings

Now when you start typing “angular.mod” inside a Typscript file (such as services.ts) you will get Intellisense completion.

Typescript-Intellisense

Good stuff, as I said. Remember to include services.js inside index.html.

And now for some structure

Apparently, we’re dealing with playlists here. Let’s create a model for that


class Playlist {
    constructor(public id: number, public title: string){}
}

In case you’re wondering what this is doing exactly, have a look at the Typescript handbook section for classes and optionally run this code through the Typescript playground to see the resulting Javascript.
Next is a small service that holds our dummy playlist data and includes two methods (sorry, functions) to return all playlists or find a single playlist by id.


class PlaylistSvc {
    private playlists: Playlist[];
    constructor() {
        this.playlists = [
            new Playlist(1, 'Reggae'),
            new Playlist(2, 'Chill'),
            new Playlist(3, 'Dubstep'),
            new Playlist(4, 'Indie'),
            new Playlist(5, 'Rap'),
            new Playlist(6, 'Cowbell')
        ];
    }
    all() {
        return this.playlists;
    }
    find(id) {
        return this.playlists[id - 1];
    }
}

Not on my watch

What’s the benefit of using

new Playlist(1, 'Reggae')

over

{ title: 'Reggae', id: 1 }

inside the list? Well, since this.playlists has to be an array of Playlist objects, the Typescript compiler can check for a number of things:

Object type inside the array

Typescript-Wrong-Type

Number and type of constructor parameters for each object

Typescript-No-Match-Call-Target

Make sure Playlist is called as constructor, not as function

Typescript-Function-Insteadof-Constructor

All of these things could happen accidentally with plain Javascript, and I think it’s a good thing Typescript can help us here.

I have to admit that my implementation of find(id) probably leaves some room for improvement. I am sort of cheating on the indexing id here, but for the sake of clarity … Anyway, we have written this service and we need to tell Angular about it so we can get it via dependency injection.


angular.module('starter.services', [])
.service('playlistSvc', () => new starter.PlaylistSvc())

We can now use this service to refactor our already existing PlaylistsController. To do that, I copied the contents of controllers.js, deleted the file, recreated it as Typescript file (controllers.ts) and pasted the content back in. Then I added a modification to PlaylistsCtrl to define the type of playlistSvc I want injected:

.controller('PlaylistsCtrl', function ($scope, playlistSvc: starter.PlaylistSvc) {
    $scope.playlists = playlistSvc.all();
})

A similar thing happens with PlaylistController, where we additionally need $stateParams

.controller('PlaylistCtrl', function($scope, $stateParams, playlistSvc: starter.PlaylistSvc) {
    $scope.playlist = playlistSvc.find($stateParams.playlistId);
})

And to finalize: In Playlist.html template we will display the title property of our playlist object

<ion-view title="Playlist">
  <ion-content class="has-header">
    <h1>Playlist <i>{{playlist.title}}</i></h1>
  </ion-content>
</ion-view>

Now, when we navigate into the detail view for a playlist, we are presented with its name. As we continue to add members to the Playlist class, we can get access to all these members through the same mechanism.

To get the complete code for this step, refer to commit #3 on the github repository: “Refactoring playlists into service and adding type definitions”

Hope that helps
.jonas

Ionic Framework Inside a Visual Studio Cordova Application using Typescript Part 2

Part 1 explained why we are trying to use Ionic Framework together with Visual Studio Tooling – and add a little Typescript as well. We saw how the default VS Template ran in Ripple Emulator.

Part 1 – Tools and a first glance
Part 2 – Ionic meets Visual Studio
Part 3 – Enter Typescript

Now it’s time to add the Ionic-Angular bundle to our little application. The easiest way to get all you need is via NuGet Package Manager: Open it and search for “Ionic”. Then hit install, which will give you a bunch of scripts.

Nuget-Ionic

 

Open index.html and then, inside your script folder, locate ionic-bundle.js and drag it into your index.html to create a script reference. Do the same for ionic.css inside the content folder.

By doing so we prepared our Visual Studio Cordova application to host a typical Ionic application generated by Ionic tooling

$ ionic start myApp sidemenu

You can do that yourself now, if you’ve got Ionic up and running. The idea would be to run the aforementioned command – but we will only use content from www/js and www/templates to recreate the application. I will describe that process now. You can always get the code from GitHub if you prefer.

So – from file explorer, drag www/templates into your Visual Studio Solution so that it ends up parallel to the existing scripts folder. We want to reuse this completely.

Next, create an “app” folder inside the scripts folder. This is where our own application logic will live. This step is optional but it helps structuring as NuGet will install the majority of its javascript package contents into the scripts folder. To keep things consistent, also move “index.ts” from /scripts into /scripts/app and update the corresponding reference inside index.html. Notice that the file we moved has extension “.ts” while the reference says “.js”. This is because it’s a typescript file, and Visual Studio will compile it to Javascript later. It’s not there yet, as is cordova.js.

Last steps

We’re only two steps away from our goal! We just need to add two script files and modify index.html once more.

First, we need to add app.js and controller.js from www/js into our /scripts/app folder. This will give us the navigation setup as well as rudimentary controller support.

Last, we rearrange script references inside index.html and add an ng-app directive alongside the ion-nav-view directive to bootstrap our application.


<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>MagicBullet</title>

    <!-- MagicBullet references -->

    <link href="Content/ionic.css" rel="stylesheet" />
    <link href="css/index.css" rel="stylesheet" />
    <script src="cordova.js"></script>
    <script src="scripts/ionic.bundle.js"></script>
    <script src="scripts/app/index.js"></script>
    <script src="scripts/app/app.js"></script>
    <script src="scripts/app/controllers.js"></script>
</head>
<body ng-app="starter">
    <ion-nav-view></ion-nav-view>
</body>
</html>

Running Ionic application inside Visual Studio

Now just hit F5 to run the application. Ripple emulator will fire up and show you something like this.

Ripple-Ionic

Play with it for a little bit. Watch the side menu appear and how it allows you to jump to a different application part. But – see what happens when you click on one of these playlist? You’re being sent to a detail view where there’s no detail presented. No matter which playlist you select, its name is never shown.

Part 3 will change that by introducing an Angular Service – written in Typescript.

So far, this corresponds to commit #2 on the github repository: “Make Ionic sample application run”

Hope that helps
.jonas

Ionic Framework Inside a Visual Studio Cordova Application using Typescript Part 1

TL;DR:

How to use Ionic Framework (for hybrid application development) inside Visual Studio (for tooling) with Typescript (read: Javascript++, for a Javascript development overhaul)

What will we do in this series?

  1. Create an application from the Visual Studio Cordova Template
  2. Pack an application scaffolded by Ionic tooling into it
  3. Refactor it a little bit and use Typescript to add an Angular Service

Technical titles sometimes tend to get clumsy. When combining different technologies and approaches, one needs to fit a lot of words into the headline to let the reader know what one is talking about.

My alternative title was “Magic bullet combination for hybrid mobile application development” but that one’s only 12 characters short the current title and no one would have a clue what this is all about. Still, I believe the alternative title would have its justification. Let me briefly outline why.

1) Ionic

In my last post about Ionic, I gave some reasons why I believe Ionic (especially in combination with AngularJS) is a good take at hybrid mobile app development.

2) Visual Studio Cordova Template

Together with Visual Studio tooling for cordova applications, this feels like a huge push compared to Phonegap/Cordova development a year ago.

It is also complementary to Ionic in terms of tooling: It removes some setup headaches and even brings debugging to the table.

3) Typescript

Combining the above might seem pretty adventurous already. Why would someone like to bring Typescript into this mixture?

To be honest, I was curious. And Microsoft is supporting Typescript for their Cordova Template. And there is really not much to lose, as Typescript will go out of your way if needed. On the contrary, I will show how painless it is and what some of the benefits are.

If you want to hear about Typescript from someone a little bit (just a little) more destined to do so, listen to Anders Hejlsberg on the bottom of the Typescript homepage.

Part 1 – Tools and a first glance
Part 2 – Ionic meets Visual Studio
Part 3 – Enter Typescript

1-2-3 Magic bullet

The idea is to use Ionic (with Angular, needless to say) but use Visual Studio Cordova tooling support instead of Ionic’s own tooling.

To do so, we will use a standard Ionic application as scaffolded by

$ ionic start myApp sidemenu

Then we will put that into the Visual Studio Cordova template and let it run. All of this will happen in this article.

In the next installment, we will make some changes to the business logic inside that application and convert some of it to Typescript.

 

Install the tools

Before we’re installing Ionic, we should actually install Visual Studio Tooling Support for Apache Cordova a.k.a. Multi-Device Hybrid Apps. Why, you ask? Because it’s installing a lot of stuff (like Java JDK 7 and Ant as well as Ripple Emulator ) that you would have to install manually to get Ionic up and running.

This might take a few minutes to install. Take your time.

Or better yet, continue reading. Because now you are being confronted with two options:

  1. Install Ionic to do the scaffolding
  2. Go to Github and get the code I prepared for you

As we’re only using Ionic to scaffold the application and the library and CSS (alright, everything Ionic offers EXCEPT their tooling) you might as well go with option 2. Anyway, I am going to describe option 2. If you really want to go with option 1, make sure you check your setup against the more detailed setup instructions. Just sayin’.

Create an empty Apache Cordova Application with Typescript. Though we’re starting without Typescript, we will need it later

Blank Apache Cordova Template

You can then press F5 to run the application in Ripple Emulator. Your browser window should look something like that

RippleApplicationReady

This corresponds to commit Blank Cordova App with Typescript on Github.

There is nothing happening with AngularJS here. And this also has nothing to do with Ionic yet. Let’s change that in part 2.

 

Hope that helps
.jonas

Visual Studio 2013, IIS Express and SSL madness

As a quick shout out: just had that problem where I cloned an ASP.NET MVC application that is using SSL from a git repository into my freshly set up development machine, opened it in Visual Studio 2013, let it run and – nothing happened.

Except for the browser telling me that nothing happened because the site cannot be opened. Very helpful indeed.

PageNotFound

Quickly checked IIS Express in the toolbar – it says it is running and serving the site, so that’s fine.

Checked bindings in applicationhost.config and compared them to my previous settings – that’s not it.

Found a post indicating that for many people after the default VS 2013 installation, IIS Express is screwed up. So I did a repair install of IIS Express 8.

 

Now it’s working.