22
Hands On SPA Development

Hands on SPA development

Embed Size (px)

Citation preview

Hands On SPA

Development

Lab

RequirementsVISUAL STUDIO 2013 U4

GOOGLE CHROME

Lab

Overview

Lab Starter

CODE

HTTP://GOO.GL/TMULBV

THIS PRESENTATION

HTTP://GOO.GL/CHUHGY

Disclaimer 1 – This application is for

demonstration purposes ONLY. It is

meant to teach the fundamentals of

Web API and SPA Design.

A real application would have better

security. Obviously you would

require better authentication

Disclaimer 2 – Please do not use this

application to write or draw anything offensive

Index.html is the main view. You can

start up the browser from this

location

App.js is the applications view

model.

Lab ObjectiveMODIFY THE APPLICATION TO

SHOW THE REGISTERED

PLAYERS

Inspect the URL

The TelephonePictionary API on Azure also supports viewing the players registered for a

game

Let’s take a look at what the response looks like in a browser

http://telephonepictionary.azurewebsites.net/api/games/1/players

Update GameClient with new call

In the Visual Studio project, open the GameClient.cs located in the /code folder

string apiUrl = string.Format("{0}api/games/{1}/players", clientUrl, gameId);WebClient client = new WebClient();byte[] data = client.DownloadData(apiUrl);string json = UTF8Encoding.UTF8.GetString(data);var list = JsonConvert.DeserializeObject<List<string>>(json);return list;

Add an API Method Route

In the Visual Studio project, open the

GameController.cs

• Stub out the following method

Fill in the API method implementation

In the Visual Studio project, open the GameController.cs – Now let’s fill in the

implementation for GetPlayersForGame

Instead of a simple Ok() result – let’s have it return the data from the GameClient call:

Ok(GameClient.GetPlayersForGame(gameId));

Once complete; you should be able to test your new API call in a browser

http://localhost:25085/api/games/1/players (the port number will be different in your

project)

Add API Call in JavaScript

In /app/js/api-client.js add the following function. This is what will enable your application to

retrieve the same players from the server.

getGamePlayers = function (obj) {

$.ajax({

url: "../api/games/" + obj.GameId + "/players",

contentType: 'application/json',

method: 'GET',

success: function (data) {

obj.Callback(data);

}

})

}

Add a new view in the HTML

In index.html add the following markup before the closing container div (on line 175)

<div data-bind="visible: CurrentScreen() == 'PlayersList'">

<h2>All Players in game</h2>

<ul class="list-group" data-bind="foreach: AllPlayers">

<li class="list-group-item">

<span data-bind="text: $data"></span>

</li>

</ul>

</div>

Change the player count

In index.html, change line from:

<span data-bind="text: NumberOfPlayers"></span>

To:

<a href="#" data-bind="click: $root.PlayersClicked"><span data-bind="text:

NumberOfPlayers"></span></a>

Now we need to create the “PlayersClicked” function on the view model to hook everything

up

Update the view model

In app.js, add the following on line 19. This is what will hook everything together. When the

user clicks the “players” link, we will make a RESTful call back to the server to pull the players for

the selected game.

self.AllPlayers = ko.observableArray([]);

self.PlayersClicked = function (row) {

getGamePlayers({

GameId: row.Id,

Callback: function (data) {

self.AllPlayers(data);

}

});

}

Run the application

Browse to index.html (be sure to do a SHIFT-REFRESH to load your changes). What happens

when you login?

Using the Chrome Developer Tools (F12), you can see if you have any JavaScript errors on the

page. If you did everything correctly you should not have any

When you click the “number of players” link on each game, nothing happens though. Why?

View Model update to change views

Change the implementation of the PlayersClicked function in app.js – switching the view

after the data is loaded from the server will cause the application to display the players

view

self.PlayersClicked = function (row) {

getGamePlayers({

GameId: row.Id,

Callback: function (data) {

self.AllPlayers(data);

self.CurrentScreen("PlayersList");

}

});

}

Testing is my responsibility too

“By iteratively developing

your tests, you will be

subtly influencing the

application design

We need to think of functional

tests as a construction deliverable

“Mocking frameworks are a developer’s best friend