Solving The Azure Functions Challenge With JavaScript

Burke Holland
Jun 15, 2017 · 8 min read

If you’ve found this post, you’re probably looking for help on how to solve the Azure Functions Challenge using JavaScript. If that isn’t why you’re here, and you don’t know what the Azure Functions Challenge is or what Azure Functions are or even what Azure is, that’s ok too! You’ll learn a lot just by going through this exercise. Click here to get started with the challenge.

Let’s get right to it. This is how I solved the Azure Functions Challenge with JavaScript.

Ping Pong

The first puzzle is pretty simple as it just wants to show you how to create a function and have it return a value.

Create a new Generic HTTP Function with JavaScript. Now that you’ve done that, you already have a function that returns a response. All you need to do is modify it to echo back out the value you received as the ping but with a key of “pong”. It should look something like this.

module.exports = function (context, req) {    // Check if we got a ping property
if(req.body && req.body.ping) {
context.res = {
body: { 'pong': data.ping }
};
}
else {
context.res = {
status: 400,
body: { error: 'You gotta ping to pong'}
};
}
context.done();
}

Pretty easy. This is the most fundamental way Azure Functions work. It’s about to get more complicated pretty quickly.

Decipher Text

This is exercise is a simple translation of a series of numbers into words. Kind of like a Little Orphan Annie Decoder Ring.

Image for post
Image for post

Create another JavaScript HTTP Trigger Function in the same project space.

Image for post
Image for post

This time the challenge is going to send you an object that contains a unique key, a msg string of numbers and a cipher which maps two digit numbers to characters. They want you to…

  • Split the msg portion into two digit chunks
  • Look those chunks up in the cipher object in order to “decipher” the message

First, let’s look at splitting the string of numbers into 2 digit sets. There are a few ways to do this…

Loop

You could loop over the number and just count your way through it, storing the numbers in an array.

// break the msg into an array of 2 digit numbers
let result = [];
for (var x = 0; x < data.msg.length; x += 2) {
result.push(data.msg.substring(x, x + 2));
}

Regex

If the word “regex” makes you queasy, you’re in good company. Everyone feels that way. There are only two types of people in the world: those that hate regex and those who won’t admit it.

Image for post
Image for post

You don’t need to master regex to use it. Just know what it can do and then Google. That’s how the rest of us are doing it.

In the case of this string, the regular expression to split the number into two character sets is dead simple…

// break the msg into an array of two digit numbers
let result = req.body.msg.match(/.{1,2}/g);

Now that we’ve got the array of numbers, we need to find their letter equivalents in the cipher object. Unfortunately, the cipher object is not at all in the format we need it. The letters are the keys and the numbers are the values. That’s going to force us to write a loop.

Or, we can just use Underscore to invert the keys and values in the object because Underscore is amazing. Come at me with your Lodash.

We can just install Underscore from npm because you can do that in the Azure Portal.

Installing NPM Modules In Azure Functions

You can install npm modules via the web interface for Azure functions just like you would do on a terminal. If you are logged into your Azure Portal, just go to the Function project, then select “Platform features” and open the console. Then it’s just npm install underscore.

Image for post
Image for post

If you’re using the free Try Azure sandbox, you don’t have access to the console so you can’t install npm modules. Instead you can use this handy function that I shamelessly stole from StackOverflow. Shout out to user tnanoba!

let invert = (obj) => {
var ret = {};
for(var key in obj){
ret[obj[key]] = key;
}
return ret;
}

At this point, all we have to do is loop over the array of two digit numbers and compose the result.

var _ = require('underscore');module.exports = function (context, req) {    if (req.body && req.body.key && req.body.msg && req.body.cipher) {

// break the msg into an array of two digit numbers
let twoDigitSeries = req.body.msg.match(/.{1,2}/g);

// invert the object/keys on the cipher to make it easy to
// read with array notation
let invertedCipher = _.invert(req.body.cipher);
// iterate over the two digit series and use
// the cipher to decode the message
let result = '';
twoDigitSeries.forEach((item) => {
result += invertedCipher[item];
});
context.res = {
// status: 200, /* Defaults to 200 */
body: { "key": req.body.key, "result": result }
};
}
else {
context.res = {
status: 400,
body: "Please pass key, msg and cipher parameters"
};
}
context.done();
};

On to the next challenge!

Sort Array

This one is going to send us a key and an array and it wants us to store the array by it’s key somewhere and then return it in a second function. This is great because we get to look at input and output bindings in Azure Functions as well as Azure Table Storage.

When it comes to data, you can think of bindings like this: Input bindings are for when you want to read data. Output bindings are when you want to write data. You can create bindings to all sorts of database stores, including CosmosDB and other fancy things, but for our purposes, simple Azure Table Storage will work just fine.

Step 1

Create a new HTTP Trigger function. Select the “integrate” option beneath the function and then create a new output binding. You can select Azure Table Storage when it asks what kind of binding you want to create.

Image for post
Image for post

Once the binding is created, you’ll need to configure it. The “Table parameter name” is the name that you will use to access the table storage in your function. It can be anything. The “Table name” is the name of the table that will be created in storage. Whatever name you give your table here is the same name you will use to access it in the next function. Lastly, you need to choose or select a “Storage account connection”.

Image for post
Image for post

Now that the binding is created, we can access the table by calling context.bindings.outputTable. If you recall, outputTable was our “Table parameter name”. We can write to the table storage by specifying an object with a PartitionKey, a RowKey and ArrayOfValues. The PartitionKey and RowKey are required fields. You can tack anything else you like onto the object but you have to at least have those two. In this case, we’re tacking on ArrayOfValues.

module.exports = function (context, req) {    if (req.body && req.body.key && req.body.ArrayOfValues) {        context.bindings.outputTable = { 
PartitionKey: 'MyPartitionKey',
RowKey: req.body.key,
ArrayOfValues: req.body.ArrayOfValues
}
context.res = {
body: {}
}
}
else {
context.res = {
status: 400,
body: "Please pass a key and ArrayOfValues parameters"
};
}
context.done();
};

Notice that you never to call save on the outputTable. The save happens automatically. Simply setting the outputTable value is enough.

That’s all we have to do to store the key and ArrayOfValues in Azure Table Storage. On to step 2!

Step 2

In step 2, they are simply going to pass the key that they passed to the first function and we are going to retrieve the ArrayOfValues from table storage.

To do that, create a new HTTP Function. Go to the “Integrations” item and add a new input binding. To configure the input binding…

  • remember that the “Input parameter name” can be whatever you want. It’s just the name that the table will have when you reference it in your function.
  • The “Input table name” needs to be the same name you specified in step 1. That’s how Azure knows what table to read from.
  • The partition key needs to be the same partition key you specified in step 1.
  • The row key is going to be dynamic. It is passed into the function in the HTTP call. You can bind to it directly here using {key} syntax. Any parameter that is passed into the function can be bound to in bindings this way.

Your final configuration for the input binding should look something like this…

Image for post
Image for post

Now we can access the inputTable on the context.bindings object and read from it. It will only contain our table entry that was created in step one because we’ve already passed the key in the binding.

module.exports = function (context, req) {    if (req.body && req.body.key) {        let key = req.body.key;
let ArrayOfValues = JSON.parse(context.bindings.inputTable.ArrayOfValues);
// sort the array
let sortedArray = ArrayOfValues.sort((a, b) => { return a - b });
context.res = {
// status: 200, /* Defaults to 200 */
body: { key: key, ArrayOfValues: sortedArray }
};
}
else {
context.res = {
status: 400,
body: "Please pass a name on the query string or in the request body"
};
}
context.done();
};

Note that we have to parse the ArrayOfValues on the input table as it appears that Azure Table Storage stores our array as a string. Then we sort the array numerically per the challenge.

That’s it! And now you know how to use input and output bindings as well as Azure Table Storage. We call that a “two-fer”.

GitHub Deploy

The last step just has you deploy from GitHub to Azure functions, because you can. It’s really just a matter of filling out a form and selecting a resource group.

Challenge Accepted, Challenge Completed

I really liked the Functions Challenge as I’m new to this world of Serverless applications. I don’t fully understand all of it and we’re all learning every day. One thing is for sure, we are at the very beginning of the Serverless revolution, and Azure Functions is a great place to get onboard.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store