# Calculator Application Using IronJS and WPF by invoking an external JavaScript file Posted by in WPF category on for Beginner level | Points: 250 | Views : 3467 Rating: 5 out of 5
1 vote(s)

In this article, we will build a simple calculator by using WPF and will use IronJS for writing the various calculator operations.We are using an external JavaScript as our dynamic scripting language.This Java Script file will have all the functions that the Calculator will use. Download source code for Calculator Application Using IronJS and WPF by invoking an external JavaScript file

Recommendation

## Introduction

In the previous article , we have seen how to invoke a dynamic scripting language (e.g. Java Script) using Iron Python.But in that article, we were building the functions programatically.In this article, we will extend our same example to demonstrate the power of IronJS of invoking an external Java Script file.The development environment is Microsoft Visual Studio Community 2015.

## Environment Setup

Let's create a solution file and add two project, one WPF(CalciPL) and another Class Library(CalciBL) projects.Choose the Class Library(CalciBL) project, click on Managed Nuget Packages. In the Search box Type "IronJS" and click "Search" Click on the Install button to install "IronJS". We are using version 0.2.0.1 Once installed, we will get the below screen Now we are good to go for writing our Business Logic(s)

## Using the code

Let us first create a javascript file say CaliOperations.js which will have the below functions

```/*
Purpose: For Addition of two numbers
*/

{
return a+b;
}

/*
Function Name: Sub
Purpose: For Subtraction of two numbers
*/

function Sub(a,b)
{
return a-b;
}

/*
Function Name: Mul
Purpose: For Multiplication of two numbers
*/
function Mul(a,b)
{
return a*b;
}

/*
Function Name: Div
Purpose: For Division of two numbers
*/
function Div(a,b)
{
return a/b;
}
```

Let us write the below code in the CaliOperation.cs file

```using IronJS;
using System;

namespace CalciBL
{
public class CaliOperation
{
public int CaliOperations(int a, int b, string @operator)
{
const string FILEPATH = @"D:\CaliOperations.js";

string operation = string.Empty;

// Instantiate the IronJS Engine
var context = new IronJS.Hosting.CSharp.Context();

context.ExecuteFile(FILEPATH);

//Set the operation mode as per the operator choosen
switch (@operator)
{
case "+":
break;

case "-":
operation = "Sub";
break;

case "*":
operation = "Mul";
break;

case "/":
operation = "Div";
break;
}

//fo holds the needed JS function
FunctionObject fo = context.Globals.GetT<FunctionObject>(operation);

//invoke the JS dynamic method
BoxedValue bv = fo.Call(context.Globals, Convert.ToDouble(a), Convert.ToDouble(b));

//unboxing the unknown values to a known value
double result = bv.Unbox<double>();

//Execute method runs the dynamic code
return Convert.ToInt32(result);
}
}
}

```

Code Explanation

The very first thing we need to perform is to instantiate the IronJS Engine which can be achieve by the below code

`new IronJS.Hosting.CSharp.Context()`

Next we are invoking the ExecuteFile method of the on the context object. The ExecuteFile caches the AST tree for the parsed "CaliOperations.js" file and uses the cache.

Next, based on the operator choosen at runtime, we are setting the operation that is defined in the "CaliOperations.js" JavaScript file.

IronJS automatically sends the function being called into the FunctionObject parameter.The FunctionObject class is derived from CommonObject.

``` //fo holds the needed JS function
FunctionObject fo = context.Globals.GetT<FunctionObject>(operation);
```

The FunctionObject has a call method that invokes the dynamic methods

``` //invoke the JS dynamic method
BoxedValue bv = fo.Call(context.Globals, Convert.ToDouble(a), Convert.ToDouble(b));
```

As can be figure out that, the Call method returns a BoxedValue type. This is a NaN-tagged struct that is used for representing values that don't have a known type at runtime.IronJS passes integers as doubles, so we need to cast them.

```Convert.ToDouble(a)
```

Finally, we are unboxing the unknown values to a known value by invoking the Unbox function

To test our function, we can write a simple Unit Test project as under

```using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace CalciBL.Tests
{
[TestClass()]
public class CaliOperationTest
{
[TestMethod()]
{
CaliOperation objCalciOp = new CaliOperation();
var expected = 60;
var actual = objCalciOp.CaliOperations(20, 40, "+");
Assert.AreEqual(expected, actual);

}

[TestMethod()]
{
CaliOperation objCalciOp = new CaliOperation();
var expected = 35;
var actual = objCalciOp.CaliOperations(-20, 40, "+");
Assert.AreNotEqual(expected, actual);

}

[TestMethod()]
public void CaliOperationSubtractionSuccessTest()
{
CaliOperation objCalciOp = new CaliOperation();
var expected = -20;
var actual = objCalciOp.CaliOperations(20, 40, "-");
Assert.AreEqual(expected, actual);

}

[TestMethod()]
public void CaliOperationSubtractionFaliureTest()
{
CaliOperation objCalciOp = new CaliOperation();
var expected = 35;
var actual = objCalciOp.CaliOperations(-20, 40, "-");
Assert.AreNotEqual(expected, actual);

}

[TestMethod()]
public void CaliOperationMultiplicationSuccessTest()
{
CaliOperation objCalciOp = new CaliOperation();
var expected = -800;
var actual = objCalciOp.CaliOperations(-20, 40, "*");
Assert.AreEqual(expected, actual);

}

[TestMethod()]
public void CaliOperationMultiplicationFaliureTest()
{
CaliOperation objCalciOp = new CaliOperation();
var expected = 35;
var actual = objCalciOp.CaliOperations(20, 40, "*");
Assert.AreNotEqual(expected, actual);

}

[TestMethod()]
public void CaliOperationDivisionSuccessTest()
{
CaliOperation objCalciOp = new CaliOperation();
var expected = 10;
var actual = objCalciOp.CaliOperations(400, 40, "/");
Assert.AreEqual(expected, actual);

}

[TestMethod()]
public void CaliOperationDivisionFaliureTest()
{
CaliOperation objCalciOp = new CaliOperation();
var expected = 35;
var actual = objCalciOp.CaliOperations(56, 40, "/");
Assert.AreNotEqual(expected, actual);

}
}
}
```

Now let us make our UI design in WPF which will be as under And the code is as under

```using CalciBL;
using System;
using System.Windows;

namespace CalciPL
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
CaliOperation objCalciOp;
public MainWindow()
{
InitializeComponent();
objCalciOp = new CaliOperation();
}

private void btnAdd_Click(object sender, RoutedEventArgs e)
{
var nums = InputValues();
txtResult.Text = Convert.ToString(objCalciOp.CaliOperations(nums.Item1, nums.Item2, "+"));
}

private void btnSub_Click(object sender, RoutedEventArgs e)
{
var nums = InputValues();
txtResult.Text = Convert.ToString(objCalciOp.CaliOperations(nums.Item1, nums.Item2, "-"));
}

private void btnMul_Click(object sender, RoutedEventArgs e)
{
var nums = InputValues();
txtResult.Text = Convert.ToString(objCalciOp.CaliOperations(nums.Item1, nums.Item2, "*"));
}

private void btnDiv_Click(object sender, RoutedEventArgs e)
{
var nums = InputValues();
txtResult.Text = Convert.ToString(objCalciOp.CaliOperations(nums.Item1, nums.Item2, "/"));
}

private Tuple<int, int> InputValues()
{
var num1 = Convert.ToInt32(txtNum1.Text);
var num2 = Convert.ToInt32(txtNum2.Text);
return Tuple.Create(num1, num2);
}
}
}
```

Now run the application and we can feel the taste of our simple calculator. ## Conclusion

So in this article we have seen how to invoke an external dynamic language like Java Script file functions using IronPython.Hope this will be helpful.Attached is the zipped file.Thanks for reading. Full Name: Niladri Biswas (RNA Team)
Member Level: Platinum
Member Status: Member,Microsoft_MVP,MVP
Member Since: 3/17/2015 2:41:06 AM
Country: India
-- Thanks & Regards, RNA Team

Login to vote for this post.

Comment using (Author doesn't get notification)