AngularJS: Custom Filters

Here are some basics on how to create your own Angular custom filters. Below I have created a controller with an array of numbers starting from 1 to 10 and I am going to write a custom filter for filtering even numbers and one for odd numbers.

app.controller('AppController', ['$scope', function($scope) {
		$scope.numbers = [1,2,3,4,5,6,7,8,9,10];
	}
]);

To filter even numbers only I created a filter called EvenNumbersOnly which is a function that takes an array of numbers and check each value to see they are even numbers:

app.filter('EvenNumbersOnly', [function() {
		return function(numbers) {
			var evenNumbers = [];
			for (idx in numbers)
			{
				if ((numbers[idx] % 2) == 0)
				{
					evenNumbers.push(numbers[idx]);
				}
			}
			return evenNumbers;
		}
	}
]);

For filtering odd numbers I have done the same thing except it only check for odd numbers šŸ™‚

app.filter('OddNumbersOnly', [function(){
		return function(numbers) {
			var oddNumbers = [];
			for (idx in numbers)
			{
				if ((numbers[idx] % 2) == 1)
				{
					oddNumbers.push(numbers[idx]);
				}
			}
			return oddNumbers;
		}
	}
]);

So now we have our filters ready to be used I will create a html page that will display the original complete set of numbers in the first div element, then I display a set of even numbers using the EvenNumbersOnly filter in the second div element, and then I display a set of odd numbers using the OddNumbersOnly filter in the third div element. Please note that the filter must be used with a pipe after the value you want to filter with:

<html ng-app="app.demo">
	<head>
	<title>Learn AngularJS - Filters</title>
	<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.14/angular.min.js"></script>
	<script src="app.js"></script>
	</head>
	<body ng-controller="AppController">
		<div>
		Numbers: {{ numbers }}
		</div>
		<div>
		Even Numbers: {{ numbers | EvenNumbersOnly }}
		</div>
		<div>
		Odd Nimbers: {{ numbers | OddNumbersOnly }}
		</div>
	</body>
</html>

Download Source Code

AngularJS: Controller Functions

To create a controller function that can be use with an element’s event attribute, you need to define a function with it’s implementation in it and then attached it to the $scope.

Below I have created a new Javascript file called app.js with a controller called AppController. In the $scope I have a property for storing text and one for attaching a function called onClick. When the onClick function is invoked, the message property will be set with a message ‘Hello, World!’:

var app = angular.module('app.demo', []);

// Controllers
app.controller('AppController', ['$scope', function($scope) {
		$scope.message = '';
		$scope.onClick = function() {
			$scope.message = 'Hello, World!';
		}
	}
]);

Below I create a html page with body that usesĀ the AppController controller, I have a input element that is a button type and I use ng-click to bind the function that I have create in the controller. I have created a div that will display the message property every time the button is clicked:

<html ng-app="app.demo">
	<head>
	<title>Learn AngularJS - Functions</title>
	<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.14/angular.min.js"></script>
	<script src="app.js"></script>
	</head>
	<body ng-controller="AppController">
		<input type="button" ng-click="onClick()" value="Click Here" />
		<div><h1>{{message}}</h1></div>
	</body>
</html>

Download Source Code

AngularJS: Sharing Data Between Controllers

To share data between controllers, first create a service that will hold your data.

var myApp = angular.module("app.demo", []);

myApp.factory("Data", function(){
	return {
		message: "Hello, World"
	};
});

Then you inject the factory into each controller.

myApp.controller("AppController1", ["$scope", "Data", function($scope, Data) {
	$scope.data = Data;
}]);

myApp.controller("AppController2", ["$scope", "Data", function($scope, Data) {
	$scope.data = Data;
}]);

Then create a html page with the following markup. You can see below there is two controllers receiving the input value and each one is bind to the same factory called Data.

<html ng-app="app.demo">
	<head>
	<title>Learn AngularJS - Sharing Data Between Controllers</title>
	<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.14/angular.min.js"></script>
	<script src="SharingDataDemo.js"></script>
	</head>
<body>
	<div ng-controller="AppController1">
		<input type="text" ng-model="data.message" />
		<div>{{data.message}}</div>
	</div>
	<div ng-controller="AppController2">
		<input type="text" ng-model="data.message" />
		<div>{{data.message}}</div>
	</div>
</body>
</html>

This demo can be downloaded from my GitHub repository: https://github.com/csharpguy76/LearnAngularJS

AngularJS: Data Binding

In AngularJS data binding is very straight forward, you need to assign a model in the ng-model attribute and on your page you can read the model from anywhere on the page either by expressions or ng-model from another element.

<html ng-app="app.demo">
<head>
	<title>Learn AngularJS - Data Binding</title>
	<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.14/angular.min.js"></script>
	<script src="AppController.js"></script>
</head>
<body ng-controller="AppController">
	<input type="text" ng-model="message" />
	<div>{{message}}</div>
</body>
</html>

Above is an example of an input element taking a message as a model and then display the message result with double curly braces. The message model comes from theĀ controller’s $scope eg. $scope.message.

angular.module("app.demo",[])
.controller("AppController", ["$scope", function($scope){
	$scope.message="default message";
}]);

You can download the original source code from GitHub: https://github.com/csharpguy76/LearnAngularJS

 

C#: How to Join Two List Using Lambdas Expression

Joining two Lists using Lambdas expression is very simple, lets say we have a inventory of computer products and we have a bunch of purchase orders to process.

So what I am going to do to demonstrate this is to create a class called Product that will have a string property for storing the product’s name and a decimal property for storing the unit price and a property for the product’s id.

	
public class Product
{
	public int Id {
		get;
		set;
	}
	public string Name {
		get;
		set;
	}
	public decimal UnitPrice {
		get;
		set;
	}
}

Then I create a class called Order that will have a property for the order number as a string, product id as an integer and quantity as a decimal.

public class Order
{
	public int ProductId {
		get;
		set;
	}
	public string Number {
		get;
		set;
	}
	public int Quantity {
		get;
		set;
	}
}

So now I have my classes created I will create a List of products and orders with values. For the Join to work, both lists must have a common reference, and that reference is the Product’s Id.

List<Product> products = new List<Product> {
	new Product { Id = 1, Name = "1TB SSD Drive", UnitPrice = 99 },
	new Product { Id = 2, Name = "Keyboard", UnitPrice = 39.95M },
	new Product { Id = 3, Name = "24 inch Monitor", UnitPrice = 124.99M }
};

As you can see below each order has a referece to a Product Id and a product can 0 to many orders.

List<Order> orders = new List<Order> {
	new Order { Number = "A100", ProductId = 2,  Quantity = 100 },
	new Order { Number = "QZ123", ProductId = 1, Quantity = 10 },
	new Order { Number = "1234", ProductId = 2, Quantity = 55 }
};

To join these two list you would use the Lambdas Join expression. Below I query the orders list and join it with the products list by the order’s ProductId and the product’s Id. Then I return each result with a custom object with all the values in it.

var results = orders.Join (products, o => o.ProductId, p => p.Id, ((o, p) => new { 
	ProductName = p.Name,
	UnitPrice = p.UnitPrice,
	Number = o.Number,
	Quantity = o.Quantity,
	TotalCost = p.UnitPrice * o.Quantity
})); 

To see the finishing result I write a foreach on the resultsĀ andĀ output the values to the console.

foreach (var order in results) {
	Console.WriteLine ("Order No: {0}, Product: {1}, Qty: {2}, Unit Price: {3}, Total Cost: {4}", order.Number, order.ProductName, order.Quantity, order.UnitPrice, order.TotalCost);
}
Shares