JSPM with SystemJS, ES6, AngularJS, TypeScript and ASP.NET Core – Part 4 [Integration]

Note: in this series I’m using some UNIX commands like touch and mkdir. If you’re using Windows, those commands can be ran if you’re using cmder, the appropriate related command for Windows or creating files and folders using the GUI.


Prerequisites

In the first three parts of this series we learned how to setup and create the frontend and the backend project. Now we’re going to integrate both and simulate a real world application.

Remember again this tutorial is targeted to UNIX users (more specifically MacOS), if you’re using Windows be sure to adjust accordingly where I haven’t done so already. Or you could achieve similar results by using cmder on Windows, I highly recommend using it!


Part 4 – Integrating the backend with the frontend

Ok! So now we start part 4! Integration, integration! Let’s see how we can integrate both projects (frontend and backend).

This part is long so I’m just going to post the code and then explain everything at the bottom

The first thing we’re going to do is create a folder named app.server right under src, then create a file named index.ts there. Then, create a new folder under app.server named user and inside that folder 4 new files: user.html, user.ts, user-component.ts and user-controller.ts. Our new structure is going to look like this:

Open the terminal and run the command jspm install npm:angular-resource.

Now let’s insert the following code in our user.html:

<div class="media">
  <div class="media-left">
    <a href="#">
      <img class="media-object" src="{{$ctrl.user.ImageUrl}}">
    </a>
  </div>
  <div class="media-body">
    <h4 class="media-heading">{{$ctrl.user.Name}}</h4>
    {{$ctrl.user.Content}}
  </div>
</div>

The following one on our user.ts:

export interface User {
  Name: string;
  Content: string;
  ImageUrl: string;
}

The following one on our user-controller.ts:

'use strict';

import {User} from './user';

interface IUserController {
  user: User;
  loadUser(): void;
}

export default class UserController implements IUserController {
  public user: User;
  public localResource: ng.resource.IResourceService;

  static $inject = [
    "$resource"
  ];

  constructor($resource: ng.resource.IResourceService) {
    this.localResource = $resource;
    this.loadUser();
  }

  loadUser(): void {
    var curController: UserController = this;

    this.localResource<User>('http://localhost:5000/api/users/1', {
      'get': { method: 'GET' }
    }).get().$promise.then(function(response: User) {
      curController.user = response;
    });
  }
}

And the following one on our user-component.ts:

'use strict';

import UserController from './user-controller';

export default class UserComponent implements ng.IComponentOptions {
 public controller: any;
 public templateUrl: string;
 public bindings: any;

 constructor() {
 this.bindings = {};
 this.controller = UserController;
 this.templateUrl = '/src/app.server/user/user.html';
 }
}

Then we’re going to change our index.ts under app.server file to look like this:

'use strict';

import 'angular';
import 'angular-resource';
import UserController from './user/user-controller';
import UserComponent from './user/user-component';

export default angular.module('app.server', [
  'ngResource'
])
.controller('UserController', UserController)
.component('userComponent', new UserComponent());

Now we’re going to change our index.ts under app file to look like this:

'use strict';

import appServer from '../app.server/index';

export default angular.module('app', [
  appServer.name
]);

angular.bootstrap(document.documentElement, ['app']);

Finally, we change the index.html file to:

<!DOCTYPE html>
<meta charset="utf-8">
<script src="jspm_packages/system.js"></script>
<script src="jspm.browser.js"></script>
<script src="jspm.config.js"></script>

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />

<body>
  <div id="container">
    <h1><span class="label label-warning">Ahoy!</span></h1>
    <user-component></user-component>
  </div>

  <script>
    SystemJS.import('src/app');
  </script>
</body>

If you’re using Google Chrome and receive this error:

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.

You’ll have to run Google Chrome with the flag <span class="s1">--disable-web-security</span>. On MacOS the code would be:

<span class="s1">/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --disable-web-security --user-data-dir=~/ChromeUserData/</span>

Now let’s move to the backend project! Open the project and create a new folder called Models and inside that folder a new file named User.cs. That file will look like:

namespace BlackBeard.Controllers
{
    public class User
    {
      public string Name { get; set; }
      public string Content { get; set; }
      public string ImageUrl { get; set; }
    }
}

Then create a new file under the folder Controllers. Let’s call it UserController.cs and fill it with:

using System.Collections.Generic;
using Microsoft.AspNet.Mvc;

namespace BlackBeard.Controllers
{
    [Route("api/[controller]")]
    public class UsersController : Controller
    {
        User[] users = new User[] {
              new User {
                Name = "William Kidd",
                Content = "(Scottish, 1645 - 1701)",
                ImageUrl = "http://historylists.org/images/william-kidd.jpg"
              },
              new User {
                Name = "Edward Teach \"Blackbeard\"",
                Content = "(English, 1680- 1718)",
                ImageUrl = "http://historylists.org/images/edward-teach.jpg"
              }};

        // GET: api/users
        [HttpGet]
        public IEnumerable<User> Get()
        {
            return users;
        }

        // GET api/users/5
        [HttpGet("{id}")]
        public User Get(int id)
        {
            return users[id];
        }

        // POST api/users
        [HttpPost]
        public void Post([FromBody]User value)
        {
        }

        // PUT api/users/
        [HttpPut("{id}")]
        public void Put(int id, [FromBody]User value)
        {
        }

        // DELETE api/users/5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }
    }
}

Now you can run the frontend (http-server) and the backend (dnx web) again. If everything was done correctly you should see the following result:

Now a little bit of explanation…

First of all, some things should’ve been placed in different locations. For instance, the user.ts file should’ve been placed on a different folder maybe named app.data or app.dao. The code to retrieve the resource should’ve been placed on a specific class in a different folder as well and so on. But those things are for you to fix when you create your own real world app.

Ok! So on our user.html we have pretty basic html and angular code, so I’m not going to delve deeper on that. Suffice to say that we’re accessing the controller’s variable user and then its properties:

{{$ctrl.user.ImageUrl}}

On user.ts we’re following TypeScript‘s standards and creating an interface to represent our data and typing it accordinly.

On user-controller.ts:

  1. We import the User interface
  2. Create an interface (protocol) for our controller
  3. Create the controller class implementing the interface
  4. Make use of the `static $inject` to inject dependencies on `TypeScript` code
  5. Make a request to our WebApi project using `angular`’s `$promise`

On user-component.ts we create an angular component using user.html as our template.

On app.server/index.ts:

  1. We import the needed libraries and the locally created Controller and Component
  2. Define our module, it’s dependencies and the controller and component

On app/index.ts we just define our module, import the server module and bootstrap the application.

And that’s it for part 4! Now we have a fully operational frontend and backend project communicating with each other. The goal was to stop here, but I’m going to add a fifth part to this tutorial explaining how to use a database and maybe a sixth explaining how to deploy both projects.

Both projects have been updated on GitHub!

 

RedBeard on GitHub

BlackBeard on GitHub

Stay tuned!

JSPM with SystemJS, ES6, AngularJS, TypeScript and ASP.NET Core – Part 3 [Backend]

Note: in these series I’m using some UNIX commands like touch and mkdir. If you’re using Windows, those commands can be ran if you’re using cmder, the appropriate related command for Windows or creating files and folders using the GUI.


Prerequisites

In the first two parts of this series we learned how to setup and create the frontend project. Now we’re going to create the backend project using ASP.NET Core.

Remember again this tutorial is targeted to UNIX users (more specifically MacOS), if you’re using Windows be sure to adjust accordingly where I haven’t done so already. Or you could achieve similar results by using cmder on Windows, I highly recommend using it!


Part 3 – Create a backend project using ASP.NET Core

Before we start, let’s just make sure we have everything working by running the command: dnvm list. This is my output:

Windows using cmder:

At the time of writing the current ASP.NET version is 1.0.0-RC1 as you can see. Make sure you install and use the Core CLR (disregard the Windows version, it’s not updated)

Now we’re going to prepare the project.

  1. Install Yeoman: npm install -g yo
  2. Install aspnet generator: npm install -g generator-aspnet
  3. Create a folder for your project (mine is blackbeard)
  4. Change to that folder’s root
  5. Run the command: yo aspnet
  6. With your keyboard arrow keys go down until Web API Application is selected and press enter
  7. Name your application (mine is BlackBeard) and press enter
  8. Change to the new folder that was created (in my case BlackBeard)
  9. Run dnu restore

    • OBS: in case you receive a Permission denied error run chmod +x dnu (see image):
  10. Run dnu build to make sure everything is correct:
  11. Finally, run dnx web:

To test our app, let’s use Postman or any other API tester you might use and make a request to localhost:5000/api/values. The result should be:

And that’s it for part 3! Now we have a fully operational frontend project working with JSPM, SystemJS, AngularJS and TypeScript and also a fully operational backend project running on ASP.NET Core. For our next part we’re going to integrate these two projects and have a fully working application.

RedBeard on GitHub

BlackBeard on GitHub

Stay tuned!

JSPM with SystemJS, ES6, AngularJS, TypeScript and ASP.NET Core – Part 2 [TypeScript]

Note: in these series I’m using some UNIX commands like touch and mkdir. If you’re using Windows, those commands can be ran if you’re using cmder, the appropriate related command for Windows or creating files and folders using the GUI.


Prerequisites

Part 1

In the first part of this series we learned how to setup the project. Now we’re going to adapt our project to work mainly with TypeScript. It’s just some minor configurations for organization purposes.


 

Part 2 – Using TypeScript as our main codebase

The first thing we do is add this bit of code to our jspm.config.js:

typescriptOptions: {
    target: 'es6',
    module: 'system',
    sourceMap: true,
    experimentalDecorators: true,
    emitDecoratorMetadata: true
  },

This is the result:

You can find information for each compiler flag here. Now, we’re going to change our lines from 11 to 18 to look like:

    "src/app": {
      "main": "index",
      "defaultExtension": "ts",
      "meta": {
        "*.ts": {
          "loader": "plugin-typescript",
          "format": "es6"
        }
      }
    }

As you can see, we changed the folder our module files reside and we also changed the extension of our files to .ts. After you’re done with this remove the app.js file and create a folder inside src named app (mkdir app) and then inside the folder app create a file named index.ts by running the command touch index.ts. This is what our new project structure looks like:

 

Now let’s add the following code to our index.ts file:


'use strict'
import 'angular';

let container = document.getElementById('container');
container.innerHTML = 'Ahoy, TypeScript!';

On our index.html file we change the SystemJS.import('app.js'); to SystemJS.import('src/app');.

Then run http-server on your root folder and access http://localhost:8080. This should be the result:

 

Now we are running TypeScript and also importing AngularJS (as you can see on the network tab). Now let’s try to run an example from TypeScript’s website (we’re going to use the classic Hello World! example). Change your index.ts file to look like:

class Greeter {
    constructor(public greeting: string) { }
    greet() {
        return "<h1>" + this.greeting + "</h1>";
    }
};

var greeter = new Greeter("Hello, world!");
    
document.body.innerHTML = greeter.greet();

After running the site again, this should be the output:

 

And that’s it for part 2! Now we have a fully operational frontend project working with JSPM, SystemJS, AngularJS and TypeScript. For our next part we’re going to create an ASP.NET Core project that’ll be our backend.

RedBeard on GitHub

Stay tuned!

 

JSPM with SystemJS, ES6, AngularJS, TypeScript and ASP.NET Core – Part 1 [Setup]

Note: in these series I’m using some UNIX commands like touch and mkdir. If you’re using Windows, those commands can be ran if you’re using cmder, the appropriate related command for Windows or creating files and folders using the GUI.

This tutorial is focused on MacOS but can be extrapolated to Linux and Windows. If you use Windows be sure to download cmder if you don’t already have it.

Prerequisites:

  1. Homebrew (for MacOS)
  2. NodeJS (MacOS: brew install node | Linux | Windows)
  3. Text editor (I’ll be using Visual Studio Code)
  4. cmder (only if you use Windows)

Part 1 – Setting up the project

The first thing we need to do is create a folder for our project, in my case I named it redbeard. Now, inside that folder, we run the command npm install jspm@beta.

We’re currently using the version 0.17 which is in beta. You can check your version by running jspm --version

SteinMac:redbeard eestein$ jspm --version
0.17.0-beta.11
Running against local jspm install.

After JSPM has been installed we will initialize it by running the command jspm init.

From this moment on, everything is almost automatic.

  1. “Package.json file does not exist, create it? [Yes]:” – Press enter

  2. “Init Mode (Quick, Standard, Custom) [Quick]:” – Press enter

  3. “Local package name (recommended, optional): app” – Press enter

  4. “package.json directories.lib [src]:” – Press enter

  5. “System.config browser baseURL (optional): /” – Press enter

  6. “System.config local package main [app.js]:” – Press enter

  7. “System.config transpiler (Babel, Traceur, TypeScript, None) [babel]:” – TypeScript (and press enter)

After JSPM has finished downloading everything, run jspm install npm:angular.

This will install AngularJS (currently v1.5.3). After that, run touch index.html.

This will create an index.html file that we’ll edit to look like this:


<!DOCTYPE html>
<meta charset="utf-8">
<script src="jspm_packages/system.js"></script>
<script src="jspm.browser.js"></script>
<script src="jspm.config.js"></script>

<body>

<div id="container"></div>

  <script>
    SystemJS.import('app.js');
  </script>
</body>

After that, run touch app.js.

This will create an app.js file that we’ll edit to look like this:


let container = document.getElementById('container');
container.innerHTML = 'Ahoy, matey!';

This is our current structure on Visual Studio Code (VSC from now on):

Now, let’s install Node’s http-server library by running the command npm install http-server.

Once it’s done we can run the command (on the app’s root folder): http-server.

And then access the url on our browser: http://localhost:8080
If you did everything correctly you should see this page:

That’s it for our very first app! In the next articles we’ll make some changes to start using TypeScript as our main codebase and integrate our frontend with a backend built on ASP.NET Core:

RedBeard on GitHub

See you there!

Xamarin.Forms Social Authentication with Azure Mobile Services – Part 3

Ok, in the previous two articles (part one and part two) we successfully created an app that authenticates a user using social login. Now we will learn how to get extra information from this user, like his name, email, etc.

Get extra information from the user

One of Azure’s biggest faults in my opinion is that it doesn’t provide user details that we normally need like name and email.  In order to do that the first thing we need to do is tell Azure to request that information from the providers. For this example the only extra information I’m requesting is the user’s email, if you need more just check the specific provider’s API and add those to the scope as well. Here’s how we do it:

  1. Go to your Azure account and select your Mobile Service
  2. Click on the tab Configure and scroll down to app settings
  3. Here we’ll add two settings MS_GoogleScope and MS_FacebookScope

Ok, now when Azure requests the user authentication it will request for the user’s email and we’ll be able to retrieve that information now. In the next step we need to create a custom API in our Mobile Services at Azure.

  1. Go to your Azure account and select your Mobile Service
  2. Click on the tab API and then on Create at the bottom of the page
  3. Choose a name and select your desired configuration, this is how mine looks
  4. At the script tab paste the code below
exports.get = function(request, response) {
    var currentUser = request.user;
    currentUser.getIdentities({
        success: function (identities) {
            var url = null;
            var oauth = null;
            if (identities.google) {
                url = 
		 'https://www.googleapis.com/oauth2/v3/userinfo?access_token=' 
		 + identities.google.accessToken;
            } else if (identities.facebook) {
                url = 'https://graph.facebook.com/me?access_token=' 
				+ identities.facebook.accessToken;
            } else if (identities.twitter) {
                var userId = currentUser.userId;
                var twitterId = userId.substring(userId.indexOf(':') + 1);
                url = 'https://api.twitter.com/1.1/users/show.json?user_id=' 
				+ twitterId;
                var consumerKey = process.env.MS_TwitterConsumerKey;
                var consumerSecret = process.env.MS_TwitterConsumerSecret;
                oauth = {
                    consumer_key: consumerKey,
                    consumer_secret: consumerSecret,
                    token: identities.twitter.accessToken,
                    token_secret: identities.twitter.accessTokenSecret
                };
            }

            if (url) {
                var requestCallback = function (err, resp, body) {
                    if (err || resp.statusCode !== 200) {
                        console.error('Error sending data to the provider: ', 
						err);
                        request.respond(statusCodes.INTERNAL_SERVER_ERROR, 
						body);
                    } else {
                        try {
                            var userData = JSON.parse(body);
                            response.send(statusCodes.OK, 
				{ message : userData });
                        } catch (ex) {
                            console.error(
			     'Error parsing response from the provider API: ', 
                               ex);
                            request.respond(statusCodes.INTERNAL_SERVER_ERROR,
                               ex);
                        }
                    }
                }
                var req = require('request');
                var reqOptions = {
                    uri: url,
                    headers: { Accept: "application/json" }
                };
                if (oauth) {
                    reqOptions.oauth = oauth;
                }
                req(reqOptions, requestCallback);
            } else {
                response.send(statusCodes.OK, { message : 'Error!' });
            }
        }
    });
};

This is how it looks:

What this script does is get the user that logged in, request the extra information from the providers (in this case Facebook, Google+ and Twitter) and return that information to the app.

Now let’s make some changes to the app…

The first thing I did was to create a class to deserialize the JSON we get from our custom API:

public class SocialLoginResult
{
	public Message Message { get; set; }
}

public class Message
{
	public string SocialId
	{
		get { return string.IsNullOrEmpty(Sub) ? Id : Sub; }
	}

	public string Email { get; set; }
	public string Sub { get; set; }
	public string Id { get; set; }
}

Facebook and Twitter return Id as their unique identifier for the user while Google uses Sub, that’s why I created a property named SocialId to retrieve this information regardless of provider.

Now we go back to our SocialLogin class and add this method:

private static async Task<SocialLoginResult> GetUserData()
{
	return await Client.InvokeApiAsync<SocialLoginResult>(
            "getextrauserinfo",                  
            HttpMethod.Get, null);
}

Now we change the methods for the providers AuthenticateGoogle()AuthenticateTwitter() and AuthenticateFacebook() to return SocialLoginResult instead of MobileServiceUser. This is what they will look like:

public static async Task<SocialLoginResult> AuthenticateFacebook()
{
	await Authenticate(MobileServiceAuthenticationProvider.Facebook);
	return await GetUserData();
}

Since the client has the Azure token we don’t need to do anything else here, just make a request to the API and Azure will “know” which user we’re talking about.

The final step is to change our App.cs class. We need to change all buttons to use the email instead of Azure’s id:

fbButton.Clicked += async (sender, args) =>
{
	var user = await SocialLogin.AuthenticateFacebook();
	welcomeLabel.Text = string.Format("Welcome {0}!", user.Message.Email);
};

Perfect, now we test our app, and when we return from the provider we see…

Yes, the email is there🙂

That was it, I hope it was helpful to you!

Final project on GitHub

Xamarin.Forms Social Authentication with Azure Mobile Services – Part 2

In the previous article we prepared the project. If you haven’t done that, do! It’s necessary. You can find it here.

Authenticate the user using social networks

Alright, the fun part starts now!

Let’s create our project, as I’ve mentioned here previously my preference is for the Shared project. That’s the one I created. After the project is created we are going to add some buttons to our app, they will trigger the user login.

At my App.cs’ constructor I added this code:

var welcomeLabel = new Label
{
	HorizontalOptions = LayoutOptions.CenterAndExpand
};
var fbButton = new Button
{
	Text = "Facebook",
	HorizontalOptions = LayoutOptions.CenterAndExpand,
	BackgroundColor = Color.FromHex("#3b5998")
};
var googleButton = new Button
{
	Text = "Google+",
	HorizontalOptions = LayoutOptions.CenterAndExpand,
	BackgroundColor = Color.FromHex("#d50f25")
};
var twitterButton = new Button
{
	Text = "Twitter",
	HorizontalOptions = LayoutOptions.CenterAndExpand,
	BackgroundColor = Color.FromHex("#55acee")
};

MainPage = new ContentPage
{
	Content = new StackLayout
	{
		VerticalOptions = LayoutOptions.Center,
		Children = {
			fbButton,
			googleButton,
			twitterButton,
			welcomeLabel
		}
	}
};

This is the current result:

Now we will create a class called SocialLogin to handle the authentication process. Here’s how it will look:

public static class SocialLogin
{
	private static readonly MobileServiceClient Client = 
		new MobileServiceClient("YOUR_APP_URL", "YOUR_APP_KEY");

	private static async Task<MobileServiceUser> Authenticate(
		MobileServiceAuthenticationProvider provider)
	{
		try
		{
#if __IOS__
			return await Client.LoginAsync(
				UIKit.UIApplication.SharedApplication
					.KeyWindow.RootViewController, 
					provider);
#elif WINDOWS_PHONE
			return await Client.LoginAsync(provider);
#else
			return await Client.LoginAsync(
				Xamarin.Forms.Forms.Context, 
				provider);
#endif
		}
		catch (Exception ex)
		{
			return null;
		}
	}

	public static async Task<MobileServiceUser> AuthenticateGoogle()
	{
		return await 
		 Authenticate(MobileServiceAuthenticationProvider.Google);
	}

	public static async Task<MobileServiceUser> AuthenticateTwitter()
	{
		return await 
		 Authenticate(MobileServiceAuthenticationProvider.Twitter);
	}

	public static async Task<MobileServiceUser> AuthenticateFacebook()
	{
		return await 
		 Authenticate(MobileServiceAuthenticationProvider.Facebook);
	}
}

Ok, let’s understand what’s happening there. First we create our Azure Mobile Services Client passing our Mobile Services URL and Key:

private static readonly MobileServiceClient Client = 
		new MobileServiceClient("YOUR_APP_URL", "YOUR_APP_KEY");

Then we create a method called Authenticate that will check the current platform and request Azure’s login accordingly and some extra three methods that will create a request for authentication at every provider.

Now we go back to our App.cs class to make some changes. After the declaration of our buttons we need to add this code:

fbButton.Clicked += async (sender, args) =>
{
	var user = await SocialLogin.AuthenticateFacebook();
	welcomeLabel.Text = string.Format("Welcome {0}!", user.UserId);
};

googleButton.Clicked += async (sender, args) =>
{
	var user = await SocialLogin.AuthenticateGoogle();
	welcomeLabel.Text = string.Format("Welcome {0}!", user.UserId);
};

twitterButton.Clicked += async (sender, args) =>
{
	var user = await SocialLogin.AuthenticateTwitter();
	welcomeLabel.Text = string.Format("Welcome {0}!", user.UserId);
};

So now when the user clicks on each button he/she will be directed to login at the chosen social provider and after the login is successful a message will be show at the screen:

Awesome, so our app does work, that’s great but… You probably would like to get more information from the user, right? Like his name, birthday, email, etc.

We’ll discuss that in the next article. Check it here!

Final project on GitHub

Xamarin.Forms Social Authentication with Azure Mobile Services – Part 1

In these series I’ll show you how to integrate your Xamarin.Forms app with Azure Mobile Services. The goals are:

  1. Setup the project
  2. Authenticate the user using social networks
  3. Get extra information from the user

This is a rather extensive article/tutorial, so it will be written in three parts. Each part will go over one goal, you can find part two here and part three here.

Setup the project

First things first!

In order to follow this tutorial you need your Azure Mobile Services App Url and Key. You also need to configure the services you are going to use like Facebook, Google+ and Twitter. I won’t be discussing that here, since that’s extremely well documented here. For this tutorial you only need to go through the first subject Register your app for authentication and configure App Services. After you’re done with that subject you will have your login services and also Azure Mobile Services ready to go. At this moment we won’t need anything else from Azure, only the App Url and Key, so remember to grab those. Later on the third part of this article we’ll need to go back to Azure, though.

Before we begin we need to add Azure Mobile Services library and its dependecies. To do that, we can use Xamarin’s store for iOS and Android projects:

  1. Right click the folder Components and select Get more components
  2. Search for “azure mobile services” and select it
  3. Click Add to App

For the WP project we need to go to the nuget manager:

  1. Right click the References node and select Manage nuget packages
  2. Search for “windows azure” and install Windows Azure Mobile Services package

Alrighty! That’s it for this article, if you’re in the mood, be sure to check part two now!

 

Final project on GitHub