Tag Archives: Javascript

Download file from Azure storage using Javascript

.Net is an excellent framework – if you want proof of that, try to do, even very simple things, in Javascript. It feels a bit like getting out of a Tesla and travelling back in time to drive a Robin Reliant (I’ve never actually driven either of these cars, so I don’t really know if it feels like that or not!)

If you were to, for example, want to download a file from a Blob Storage container, in .Net you’re looking at about 4 lines of strongly typed code. There’s basically nothing to do, and it consistently works. If you want to do that in Javascript, there’s a Microsoft Javascript Library.

In said library, there is a function that should get a download URL for you; it’s named getUrl:

const downloadLink = blobService.getUrl(containerName, fileId, sasKey);            

If you use this (at least, when I used this), it gave me the following error:

Signature did not match

To get around this, you can build the download link manually like this:

const downloadLink = blobUri + '/' + containerName + '/' + fileId + sasKey;

Comparing the two, the former appears to escape the question mark in the SAS.

To actually download the file, you can use this:

        // https://stackoverflow.com/questions/3749231/download-file-using-javascript-jquery
        function downloadURI(uri, name) 
        {
            var link = document.createElement("a");
            link.download = name;
            link.href = uri;
            link.click();
        }

And the final download function looks like this:

        function downloadFile(sas, storageUri,
            containerName, fileId, destinationFileName) {

            var blobService = AzureStorage.Blob.createBlobServiceWithSas(storageUri, sas);
            
            const downloadLink = storageUri +'/' + containerName + '/' + fileId + sas;

            downloadURI(downloadLink, destinationFileName);
        }

Building a list with Asp.Net Core

I’ve recently been working with Asp.Net Core to build some functionality, involving building a list of values. Typically, with Asp.Net Core using Razor, you have a form that may look something like this:

@using (Html.BeginForm("MyAction", "ControllerName", FormMethod.Post)
{
    @Html.AntiForgeryToken()
    <div class="form-group">
        @Html.LabelFor(model => model.MyValue)
        @Html.TextBoxFor(model => model.MyValue)
    </div>

    <div class="form-group">
        <button type="submit">Submit</button>
    </div>

This works really well in 90% of cases, where you want the user to enter a value and submit. This is your average CRUD application; however, what happens if, for some reason, you need to manipulate one of these values? Let’s say, for example, that you want to submit a list of values.

For the sake of simplicity, we’ll say that the controller accepts a csv, but we want to build this up before submission. You can’t simply call a controller method for two reasons: the first is that the controller will reload the page; and the second that you don’t have anywhere to put the value on the server. If this was, say, a method to create an entry in the DB, the DB entry, by definition, couldn’t exist until after the submission.

This all means that you would need to build this list on the client.

A solution

Let’s start with a very simple little feature of Html Helpers – the hidden field:

@Html.HiddenFor(model => model.MyList)

This means that we can store the value being submitted to the user, without showing it to the user.

We’ll now need to display the data being added. An easy way to do this is a very simple table (you can load existing values into the table for edit scenarios):

    <div>
        <table id="listTable">
            <tbody>
                @if ((Model?.ValueList ?? null) != null)
                {
                    @foreach (var v in Model.ValueList)
                    {
                        <tr>
                            <td>@v</td>
                        </tr>
                    }
                }
            </tbody>
        </table>
    </div>    

Pay particular attention to the Table Id and the fact that the conditional check is inside the tbody tag. Now let’s allow the user to add a new piece of data:

    <div class="form-group">
        @Html.LabelFor(model => model.NewValue)
        @Html.TextBoxFor(model => model.NewValue)
    </div>
    <div>
        <button type="button" id="add-value">Add Value</button>
    </div>

Okay, so now we have a button and a field to add the value; we also have a method of displaying those values. We’ll need a little bit of Javascript (JQuery in this case) to append to our list:

@section Scripts {
        $('#add-value').click(() => {

            const hiddenList = $('#MyList');
            const newValue = $('#NewValue');

            if (!hiddenList.val()) {
                hiddenList.val(newValue.val());
            } else {
                hiddenList.val(hiddenList.val() + ',' + newValue.val());
            }
            
            $('#listTable > tbody:last-child').append('<tr><td>' + newValue.val() + '</td></tr>');            
        });

On the button click, we get the hidden list and the new value, we then simply add the new value to the list. Finally, we manipulate the table in order to display the new value. If you F12 the page, you’ll notice that the Razor engine replaces the Html Helpers with controls that have Ids the same as the fields that they are displaying (note that if the field name contains a “.”, for example: MyClass.MyField, the Id would be MyClass_MyField).

When you now submit this, you’ll see that the hidden field contains the correct list of values.

References

https://stackoverflow.com/questions/16174465/how-do-i-update-a-model-value-in-javascript-in-a-razor-view/16174926

https://stackoverflow.com/questions/171027/add-table-row-in-jquery

https://stackoverflow.com/questions/36317362/how-to-add-an-item-to-a-list-in-a-viewmodel-using-razor-and-net-core

Creating a Car Game in React – Part 5 – Levels and Time

This is the fifth part of a series (that began here).

In the last post, we added the concept of score. The car now can collect cups while avoiding trees; however, we don’t have any concept of what happens when there are no cups left.

In this post, we’ll add levels to the game, so that when you’ve collected all the cups, you move up. We’ll also introduce a time limit to make it progressively harder (as it currently stands, it’s not much of a challenge to collect the cups because you can take all day).

The source for this post is here. Again, not everything is in the post, so please refer to the repository.

Levels

Because we are creating levels, we’ll need to track the level that we’re on, so a new state property is in order:

this.state = {
	playerX: 100,
	playerY: 100,
	windowWidth: window.innerWidth,
	windowHeight: window.innerHeight,
	playerMomentum: 0,
	playerRotation: 0,
	playerVelocityX: 0,
	playerVelocityY: 0,
	playerLives: 3,
	playerCrashed: false,
	gameLoopActive: false,
	message: "",
	score: 0,
	level: 1,
	cupCount: 1, 
	remainingTime: 0
};

If you’ve followed this through from this first post, you may be asking yourself: “Is he ever going to refactor and clean this up!?”

To which I confidently respond:

“Probably!”

Anyway, you’ll notice that we have the level, the score, the time and the cup count. Advancing through the levels is conceptually just a number; here’s the code that completes a level:

completedLevel() {
	if (this.state.level >= 10) {
		this.updateMessage("Congratulations, you've completed the game");
	} 
	this.startLevel(this.state.level + 1);
}

startLevel is a slight refactor, which essentially sets the cup count and level to the new value – we’ll come back to that shortly.

You can only complete a level by collecting enough cups, so the trigger should be in the cup collection:

collectedCup(key) {
	this.setState({ 
		score: this.state.score + 1 
	});
	this.cups = this.cups.filter(cup => cup.key != key);
	this.updateMessage("Collected cup");
	if (this.cups.length == 0) {
		this.completedLevel();
	} 
}

As soon as we’re down to 0 cups, we call completedLevel.

Time

Now it’s time to have a look at the startLevel code:

startLevel(level) { 
	this.setState({
		level: level,
		cupCount: level * 2 
	}); 
	this.obstacles = this.buildObstacles(); 
	this.cups = this.placeCups();
	this.resetCarPosition();
	this.totalLevelTimeMS = (this.TOPLEVEL - (this.state.level - 1)) * 60 * 1000
	let startLevelTimeMS = (new Date()).getTime();
	this.endLevelTimeMS = startLevelTimeMS + this.totalLevelTimeMS; 
}

We’re working out when the user is out of time, and storing that in endLevelTime. Note that none of these are in state variables – the only state variable is in updated in the game loop:

let remaining = (this.endLevelTimeMS - (new Date()).getTime()) / 1000;
if (remaining <= 0) {
	this.updateMessage("Out of time!");
	this.playerDies();
}
this.setState({
	remainingTime: Math.round(remaining)
}); 

This is at the end of the game loop: we’re updating the remainingTime state variable, but first, we calculate it and, if it’s zero, the player dies (loses a life).

We need to tweak the code for the player dying, because otherwise the timer will never get reset:

playerDies() { 
	this.setState({
		playerLives: this.state.playerLives - 1,
		gameLoopActive: false
	});
	if (this.state.playerLives <= 0) {
		this.initiateNewGame();
	} else {
		this.startLevel(this.state.level);
	}
	this.repositionPlayer();
	this.setState({ 
		playerCrashed: false,
		gameLoopActive: true
	});
}

The last part is to make the time look a bit better with another of my patented icons. GameStatus.jsx should now return the following:

    return (      
        <div className="flex-container" style={flexStyle}>
            <label style={labelStyle}>
                Lives Remaining: {props.Lives}
            </label>
            <label style={labelStyle}>
                Score: {props.Score}
            </label>
            <label style={labelStyle}>
                Level: {props.Level}
            </label>            
            
            <div style={containerStyle}>  
                <img src={clockImg} style={imgStyle} />
                <div style={textDivStyle}>{props.RemainingTime}</div>
            </div>

            <label style={labelStyle}>
                {props.Message}
            </label>
        </div>  
    );

There are some new styles here so that the time appears over the clock icon:

    const containerStyle = {
        position: 'relative',
        textAlign: 'center',
        color: 'red'
    }

    const textDivStyle = {        
        position: 'absolute',
        top: '50%',
        left: '50%',
        transform: 'translate(-50%, -50%)',
        zIndex: 1,
        fontWeight: 'bold'
    }

    const imgStyle = {
        width: '100%',
        zIndex: 0
    }

In the next part, we’ll implement a high score table.

Creating a Car Game in React – Part 3 – Collision

In this, the third post of this series, we’re going to add collision to the game. For a full list of the code, please see here.

If you’re wondering about earlier posts, please start here.

Since we’re introducing collision, we’ll also need to introduce the age old game concept of “Lives”. The premise here is that when you crash into something, you lose a life.

The first step is to add a new state variable to hold the player’s remaining lives:

this.state = {
	playerX: 100,
	playerY: 100,
	windowWidth: 1500,
	windowHeight: 1500,
	playerMomentum: 0,
	playerRotation: 0,
	playerVelocityX: 0,
	playerVelocityY: 0,
	playerLives: 3,
	gameLoopActive: false,
	message: ""
};

If you have a look in the repository, there’s a bit of refactoring, where I’ve taken some of the setState code and separated it into logical functions. I won’t list that here.

Collision Detection

At the end of the game loop, we now have a call to check if we’ve collided with anything:

if (this.detectAnyCollision()) {
	this.PlayerDies(); 
}

The collision detection code is quite straight forward, and is based on the simplistic idea that all objects can be considered rectangles. Whilst this is not precise, it’s sufficient for our purpose:

detectAnyCollision() { 
        const halfWidth = this.spriteWidth / 2;
        const halfHeight = this.spriteHeight / 2;

        let rect1 = {x: this.state.playerX - halfWidth, y: this.state.playerY - halfHeight, 
            width: this.spriteWidth, height: this.spriteHeight}

        if (this.detectOutScreen(rect1)) {
            return true;
        }

        return this.obstacles.some(a => {
            var rect2 = {x: a.props.centreX - halfWidth, y: a.props.centreY - halfHeight, 
                width: this.spriteWidth, height: this.spriteHeight}
            
            if (this.detectCollision(rect1, rect2)) {
                return true;
            } else {
                return false;
            }
        });
}

detectCollision(rect1, rect2) {
	if (rect1.x < rect2.x + rect2.width &&
	rect1.x + rect1.width > rect2.x &&
	rect1.y < rect2.y + rect2.height &&
	rect1.y + rect1.height > rect2.y) {
		return true;
	}
	return false;
}

detectOutScreen(rect1) {
	if (rect1.x < 0 || rect1.x + rect1.width > this.state.windowWidth
	|| rect1.y < 0 || rect1.y + rect1.height > this.state.windowHeight) {
		return true;
	}
	return false;
}

The collision detection code itself was pilfered from here. As you can see, all we’re doing is translating our objects into rectangles, and then seeing if they intersect each other, or if the player has left the game area.

Quick note about forEach and some

I had originally used .forEach for the detectAnyCollision() code. Whilst it would, initially make sense to a C# programmer, in fact the Javascript version of this does exactly what it says on the tin; that is, it executes for each element, and there is no way to exit early!

Player Dies and Score

Now that we have introduced collision, we should consider what to do when it happens. The usual thing in a game is that the player either “dies”, or they lose “health”. Since this is inspired by a spectrum game, we’ll go with “dies”. You saw earlier that we introduced the concept of “lives” and, because it was a spectrum, it has to be 3!

The code to deal with the player death is:

PlayerDies() { 
	this.setState({
		playerLives: this.state.playerLives - 1,
		gameLoopActive: false
	});
	if (this.state.playerLives <= 0) {
		this.initiateNewGame();
	} else {
		this.resetCarPosition();
	}
	this.repositionPlayer();
	this.setState({ 
		gameLoopActive: true
	});
}

Just a quick reminder that this isn’t a comprehensive listing of code – please see the GitHub repository for that; however, apart from the reduction in lives, the most important thing here is the gameLoopActive code.

The idea here is that we only execute the game loop while this state variable is set; which means we can stop the game loop while we’re dealing with the player’s collision.

The change in the game loop code for this is very simple:

gameLoop() {
	if (!this.state.gameLoopActive) return;

 . . . 

Crashed Car

All well and good, but as it stands, this simply results in the car stopping when it hits a tree, and then being re-positioned. We can address this by adding a small “animation” to indicate a crash. If you have a look here, you’ll see why I’ve won several awards for my graphics*!

In order to plug this in, we’re going to change the car graphic binding:

render() { 
return <div onKeyDown={this.onKeyDown} tabIndex="0">
	<GameStatus Lives={this.state.playerLives} Message={this.state.message}/>
	<Background backgroundImage={backgroundImg}
	windowWidth={this.state.windowWidth} windowHeight={this.state.windowHeight} /> 
	
	<Car carImage={this.state.playerCrashed ? brokenCarImg : carImg} 
	centreX={this.state.playerX} centreY={this.state.playerY} 
	width={this.spriteWidth} height={this.spriteHeight} 
	rotation={this.state.playerRotation} /> 
	
	{this.obstacles} 
</div>
}

So, where the crashed flag is set, we’re binding to brokenCarImg; otherwise to carImg; they are defined at the top:

import carImg from '../Assets/Car.png';
import brokenCarImg from '../Assets/Crash.png';

We also split the playerDies() function into two:

playerDying(tillDeath) {
	this.setState({
		playerCrashed: true,
		gameLoopActive: false
	});
	this.stopCar();
	setTimeout(this.playerDies.bind(this), tillDeath);
}

playerDies() { 
	this.setState({
		playerLives: this.state.playerLives - 1,
		gameLoopActive: false
	});
	if (this.state.playerLives <= 0) {
		this.initiateNewGame();
	} else {
		this.resetCarPosition();
	}
	this.repositionPlayer();
	this.setState({ 
		playerCrashed: false,
		gameLoopActive: true
	});
}

All we’re doing here is calling the first function, which effectively just changes the image and then calls the second function on a timeout. Again, don’t forget the `.bind()` when you call timeout, otherwise, you won’t be able to access `this`!

Footnotes

* I haven’t actually won any awards for graphics – I had you fooled, though!

References

https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection

https://stackoverflow.com/questions/34653612/what-does-return-keyword-mean-inside-foreach-function/34653650

https://medium.com/@benjamincherion/how-to-break-an-array-in-javascript-6d3a55bd06f6

Creating a Car Game in React – Part 2 – Steering and Obstacles

In the second part of this series, we’re going to add some steering to our car, and introduce a concept of obstacles. If you’re wondering what this is the second part of, please start here.

The GitHub repo for this post can be found here.

In the first post of the series, we added a car, and allowed the user to move it around the screen in a very crude fashion; here, we’re going to change the controls to feel a little more like a car. As with the previous post, not every single change will be here, but it will be in the GitHub repo above.

Steering and Acceleration

Let’s have a look at the controls in the Game component:

onKeyDown now looks a little different:

onKeyDown(e) {
	switch (e.which) {
		case 37: // Left
			this.playerSteer(-10);
			break;
		case 38: // Up
			this.playerAccelerate(0.3);
			break;
		case 39: // Right
			this.playerSteer(10);
			break;
		case 40: // Down
			this.playerDecelerate(-0.5);
			break;
		default:
			break;
	}
} 

So, we’re no longer simply repositioning the car, but applying forces to it. Initially, I had Down as simply a negative acceleration, meaning that if you break too hard, you go backwards! Here’s the three functions referenced above:

playerAccelerate(speed) {
	this.setState({
		playerMomentum: this.state.playerMomentum + speed
	});
}

playerDecelerate(speed) {
	if (this.state.playerMomentum > 0) {
		this.setState({
			playerMomentum: this.state.playerMomentum + speed
		});
	} else if (this.state.playerMomentum < 0) {
		this.setState({
			playerMomentum: this.state.playerMomentum - speed
		});
	}

}

playerSteer(direction) {
	this.setState({
		playerRotation: this.state.playerRotation + direction
	});
}

There are a number of new state variables, which I won’t list here. However, because we are no longer repositioning the car based on the user action, we need to apply the forces that we are changing; that is, we need a game loop.

Game Loop

The game loop code is relatively complex. Looking at this should make you seriously consider using a a game engine of some description:

gameLoop() { 
	const radians = (this.state.playerRotation - 90) * Math.PI / 180; 
	const aX = (this.state.playerMomentum * Math.cos(radians));
	const aY = (this.state.playerMomentum * Math.sin(radians));
	const velocityX = this.state.playerVelocityX;
	const velocityY = this.state.playerVelocityY;
	const velocitySq = Math.pow(velocityX, 2) + Math.pow(velocityY, 2);
	const posSq = Math.pow(aX, 2) + Math.pow(aY, 2);
	const velocityPosSq = Math.pow(velocityX * aX + velocityY * aY, 2);
	let skidFactor = (posSq == 0 || velocitySq == 0) ? 0 : 1 - (velocityPosSq / posSq / velocitySq);
	
	if (skidFactor <= 0) skidFactor = 0; 
	
	this.setState({
		playerVelocityX: (skidFactor * velocityX) + ((1 - skidFactor) * aX),
		playerVelocityY: (skidFactor * velocityY) + ((1 - skidFactor) * aY)
	}); 
	this.playerMove(
		this.state.playerX + this.state.playerVelocityX,
		this.state.playerY + this.state.playerVelocityY 
	);
	this.playerDecelerate(-(0.1 + skidFactor));
}

If you’re wondering where this brain-melting maths comes from, have a look here.

I’ve split it up in an effort to make it slightly more understandable, but the premise is that if you’re travelling fast and change direction suddenly, it doesn’t immediately turn. Again, if you’re thinking you don’t want to be messing around with this kind of thing then a lot of game engines take care of this for you.

Obstacles

Finally, we have our obstacles. There is no collision just yet, but this basically puts pictures of trees around the screen (incidentally, I did all the artwork myself, which I assume the reader to be suitably impressed by!) We’ll come back to this later to make the collision work:

buildObstacles() {
	let obstacles = [];
	const obstacleCount = Math.floor(Math.random() * 10) + 1;
	console.log('Obstacle count ' + obstacleCount);
	for (let i = 1; i <= obstacleCount; i++) {
		const centreX = Math.floor(Math.random() * this.state.windowWidth) + 1;
		const centreY = Math.floor(Math.random() * this.state.windowHeight) + 1;
		
		obstacles.push(<Obstacle key={i} image={treeImg} centreX={centreX} centreY={centreY} width={this.spriteWidth} height={this.spriteHeight} />);
	}
	return obstacles;
}

All this function does is build up an array of HTML; we then feed that into a class variable in the constructor:

constructor(props) {
	super(props);
	document.body.style.overflow = "hidden";
	this.state = {
		playerX: 100,
		playerY: 100,
		windowWidth: 1500,
		windowHeight: 1500,
		playerMomentum: 0,
		playerRotation: 0,
		playerVelocityX: 0,
		playerVelocityY: 0
	};
	this.spriteWidth = 25;
	this.spriteHeight = 25;
	this.updateWindowDimensions = this.updateWindowDimensions.bind(this);
	this.onKeyDown = this.onKeyDown.bind(this); 
	this.obstacles = this.buildObstacles(); 
}

(It’s worth noting, as an aside, that we are preventing scrolling here by setting document.body.style.overflow)

Finally, we’ll display it in the render method:

render() { 
	return <div onKeyDown={this.onKeyDown} tabIndex="0">
		<Background backgroundImage={backgroundImg}
		windowWidth={this.state.windowWidth} windowHeight={this.state.windowHeight} /> 
		
		<Car carImage={carImg} centreX={this.state.playerX} 
		centreY={this.state.playerY} width={this.spriteWidth}
		height={this.spriteHeight} rotation={this.state.playerRotation} /> 
		
		{this.obstacles} 
	</div>
}

This technique allows you to build an array of HTML objects dynamically. The thing to notice here is the ‘key’ that we’re passing through; if you don’t pass this, you’ll start getting the following error:

Each child in a list should have a unique “key” prop.

In the next post, we’ll introduce collision.

References

https://stackoverflow.com/questions/5192983/calculating-x-y-movement-based-on-rotation-angle

https://gamedev.stackexchange.com/questions/172571/how-to-implement-a-slight-skid-in-a-car-game

https://stackoverflow.com/questions/39962757/prevent-scrolling-using-css-on-react-rendered-components

Creating a Basic Web Site from an Asp.Net Core Empty Project

I recently wanted to do a very quick proof of concept, regarding the use of setInterval versus setTimeout after reading that setTimeout was referable if you were calling the same function very rapidly. I thought I’d note down my journey from File -> New Project to having the POC running so that next time, I don’t have to re-lookup the various parts.

File -> New Project

If you create a brand new Asp.Net Core 2.1 project, select empty project, and then run the generated code, you’ll see this:

This is generated by a line in Startup.cs:

app.Run(async (context) =>
{
    await context.Response.WriteAsync("Hello World!");
});

The target here is to get to a situation where the blank app is serving an HTML page with some attached Javascript as fast as possible. Here, I’ve got exactly three steps.

Step 1 – Create the HTML File

The application can only serve static files (HTML is considered a static file) from the wwwroot folder. The internal structure of this folder doesn’t matter, but that’s where your file must go:

The contents of this file are as follows:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <p>test</p>
</body>
</html>

This won’t actually do anything yet, because by default, Asp.Net Core does not serve static files, nor does it know the enormous significance of naming something “Index”.

Step 2 – Configure Asp.Net

Startup.cs is where all the magic happens; this is what it looks like out of the box:

public class Startup
{
    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        
    }
 
    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
 
        app.Run(async (context) =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    }
}

The `context.Response.WriteAsync` goes, and instead we tell Asp.Net Core to serve static files, and the call to `UseDefaultFiles` means that it will search for Index or Default files. It’s also worth pointing out that the order of these matters:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
            
    app.UseDefaultFiles();
    app.UseStaticFiles();                                    
}

Now it loads the Index.html. So technically it was only two steps – although we haven’t referenced any Javascript yet.

Step 3 – Adding the javascript… and let’s do something funky

Change the HTML to give the paragraph an ID and an absolute position. Also, reference the file site.js:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <script src="site.js"></script>
</head>
<body>
    <p id="testElement" style="position:absolute">test</p>
</body>
</html>

Obviously, without adding site.js, nothing will happen (it also needs to be in wwwroot):

The Javascript code for that new file is here:

var divxPos = 0;
 
window.onload = function () {
    runCode();
};
 
function runCode() {
    var test = document.getElementById("testElement");    
    test.style.left = divxPos++ + 'px';    
 
    setTimeout(() => runCode(), 50);
};

If you run it, you’ll find the text running away with itself!

Short Walks – Submit a single row of data in ReactJS

While looking into the react sample app, I came across a scenario whereby you might need to pass a specific piece of data across to an event handler. A lot of the online examples cover data state; but what happens when you have a situation such as the one in the sample app; consider this:

In this instance, you want to pass the temperature of the line you’ve selected. The solution is quite simple, and documented here:

private renderForecastsTable(forecasts: WeatherForecast[]) {
    return <table className='table'>
        <thead>
            <tr>
                <th>Date</th>
                <th>Temp. (C)</th>
                <th>Temp. (F)</th>
                <th>Summary</th>
            </tr>
        </thead>
        <tbody>
        {forecasts.map(forecast =>
            <tr key={ forecast.dateFormatted }>
                <td>{ forecast.dateFormatted }</td>
                <td>{ forecast.temperatureC }</td>
                <td>{ forecast.temperatureF }</td>
                <td>{forecast.summary}</td>
                <td><button onClick={(e) => this.handleClick(e, forecast)}>Log Temperature!</button></td>
            </tr>
        )}
        </tbody>
    </table>;
}

Here, we’re passing the entire forecast object to the handler; which looks like this:

handleClick = (event: React.FormEvent<HTMLButtonElement>, forecast: WeatherForecast) => {
    console.log("timestamp: " + event.timeStamp);
    console.log("data: " + forecast.temperatureC);
}

https://reactjs.org/docs/forms.html

https://reactjs.org/docs/handling-events.html

Adding a New Screen to the React Template Project

In this post I started looking into ReactJS. Following getting the sample project running, I decided that I’ve try adding a new screen. Since it didn’t go as smoothly as I expected, I’ve documented my adventures.

The target of this post is to create a new screen, using the sample project inside Visual Studio.

Step 1

Create a brand new project for React:

If you run this out of the box (if you can’t because of missing packages then see this article), you’ll get a screen that looks like this:

Step 2

Add a new tsx file to the components:

Here’s some code to add into this new file:

import * as React from 'react';
import { RouteComponentProps } from 'react-router';
 
 
export class NewScreen extends React.Component<RouteComponentProps<{}>, {}> {
    public render() {
        return <div>
            <h1>New Screen Test</h1>
        </div>;
    }
}
 

The Javascript as HTML above is one of the things that makes ReactJS an appealing framework. Combine that with Typescript, and you get a very XAML feel to the whole web application.

Step 3

Add a link to the Navigation Screen (NavMenu.tsx):

<div className='navbar-collapse collapse'>
    <ul className='nav navbar-nav'>
        <li>
            <NavLink to={ '/' } exact activeClassName='active'>
                <span className='glyphicon glyphicon-home'></span> Home
            </NavLink>
        </li>
        <li>
            <NavLink to={ '/counter' } activeClassName='active'>
                <span className='glyphicon glyphicon-education'></span> Counter
            </NavLink>
        </li>
        <li>
            <NavLink to={ '/fetchdata' } activeClassName='active'>
                <span className='glyphicon glyphicon-th-list'></span> Fetch data
            </NavLink>
        </li>
        <li>
            <NavLink to={'/newscreen'} activeClassName='active'>
                <span className='glyphicon glyphicon-th-list'></span> New screen
            </NavLink>
        </li>
 
    </ul>
</div>

If you run this now, you’ll see the navigation entry, but clicking on it will give you a blank screen. It is just that scenario that motivated this post!

Step 4

Finally, the routes.tsx file needs updating so that it knows which screen to load when:

import * as React from 'react';
import { Route } from 'react-router-dom';
import { Layout } from './components/Layout';
import { Home } from './components/Home';
import { FetchData } from './components/FetchData';
import { Counter } from './components/Counter';
import { NewScreen } from './components/NewScreen';
 
export const routes = <Layout>
    <Route exact path='/' component={ Home } />
    <Route path='/counter' component={ Counter } />
    <Route path='/fetchdata' component={FetchData} />
    <Route path='/newscreen' component={NewScreen} />
</Layout>;

Forcing an NPM Restore

I’ve recently started looking into the Javascript library ReactJS. Having read a couple of tutorials and watched the start of a Pluralsight video, I did the usual and started creating a sample application. The ReactJS template in VS is definitely a good place to start; however, the first issue that I came across was with NPM.

Upon creating a new web application, I was faced with the following errors:

The reason being that, unlike NuGet, npm doesn’t seem to sort your dependencies out automatically. After playing around with it for a while, this is my advice to my future self on how to deal with such issues.

The best way for force npm to restore your packages seems to be to call

npm install

either from Powershell, or from the Package Manager Console inside VS.

Powershell

On running this, I found that, despite getting the error shown above, the packages were still restored; however, you can trash that file:

Following that, delete the node_modules directory and re-run, and there are no errors:

Package Manager Console

In Package Manager Console, ensure that you’re in the right directory (you’ll be in the solution directory by default, which is the wrong directory):

References

https://stackoverflow.com/questions/12866494/how-do-you-reinstall-an-apps-dependencies-using-npm

Rotate a Shape Around an Axis Using HTML5 and Javascript

Imagine, for a minute, that you want to rotate a red square around its centre… on a web page. Following on from my previous post about games using HTML5 / JS this post details how to do such a thing.

Context

Before drawing a rectangle, rotating it, or anything else, you need a context:

var canvas = document.getElementById("mainCanvas");
var ctx = canvas.getContext("2d");

Now you have a context, you can do things like clear the canvas; for example:

ctx.clearRect(0, 0, windowWidth, windowHeight);

fillRect

In HTML5, you have three methods that will be of use, and the first, and probably most important, is fillRect. It is impossible to rotate a square around its centre without a square. The syntax for fillRect is probably as you would expect:

ctx.fillRect(x, y, width, height);

rotate

The syntax for rotation is this:

ctx.rotate(rotationDegree * Math.PI / 180);

Whilst I may, during my school years, have been able to explain the sum above – I just copied it from the internet. Given the number of places where is looks exactly alike, I would guess that I’m not the first person to do that.

Just using the three lines above will give you a rotating rectangle; however, the rotation axis will be 0, 0. It took me a while to understand exactly how this works, but the key is `translate`.

translate

To me, this function is completely counter-intuitive. What it does it to offset the centre of the context by the parameters given. If the initial centre is 0, 0 (which it is by default), the following line will make it 10, 10:

ctx.translate(10, 10);

The centre of the context is 10, 10; if I call it a second time:

ctx.translate(10, 10);

The centre of the context is now 20, 20! There are two ways to reset the offset – you can simply negate the offset (by calling it with negative values), or you can call ctx.save() before the change, and ctx.restore() afterwards.

Putting it all together

So, what does all this look like in a single coherent piece of code:

        var canvas = document.getElementById("mainCanvas");
        var ctx = canvas.getContext("2d");
        ctx.clearRect(0, 0, windowWidth, windowHeight);

        var halfWidth = (iconWidth / 2);
        var halfHeight = (iconHeight / 2);

        var centreX = x - halfWidth;
        var centreY = y - halfHeight;

        ctx.fillStyle = "#FF0000";
        ctx.translate(centreX, centreY);
        ctx.rotate(rotationDegree * Math.PI / 180);
        ctx.fillRect(-halfWidth, -halfHeight, iconWidth, iconHeight);

        ctx.translate(-centreX, -centreY);

The key part to note here is the call to fillRect. Because the translate has now set the centre to be the centre of the drawn image, the image needs to be positioned at -(image width / 2).

… and you, too can have a spinning red rectangle on your screen.

References

http://www.w3resource.com/html5-canvas/html5-canvas-translation-rotation-scaling.php

https://gist.github.com/geoffb/6392450