In this part, we'll dive into building the Session Flash module. If you haven't seen Part 1 yet, please read it first because we're building on code we wrote there.

In part 2, we'll build the Session Flash module

In Angular, it's good practice to use directives whenever we want to make changes to the DOM. It's time to define our todoFlash directive.

directives.js

(function(angular) {

angular.module('todoDirectives', [])
.directive('todoFlash', function() {
return {
restrict: 'AE',
replace: true,
templateUrl: 'views/error.html'
}
})

})(angular);
Since we've told the directive to look for error.html, let's go define it now.

error.html

Note: this file will go under the views directory. Don't know where that is? Go read Part 1 and don't cheat yourself out of learning this fully. That said, here it is :) We're going to utilize the Bootstrap modal component to make a Session Flash.
<div class="modal fade" >
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title"></h4>
</div>
<div class="modal-body"></div>
</div>
</div>
</div>
and we should put a directive element in our index.html

index.html

<!DOCTYPE html>
<html>
<head lang="en">
...
</head>
<body ng-app="todoApp">

<todo-flash></todo-flash>

<div class="container" ng-controller="MainController" style="margin-top: 20px;">
<div class="row">
<div class="col-md-12">
<ng-include src="'views/list.html'"></ng-include>
</div>
</div>
</div>

...
</body>
</html>

What we want is a function we can call from any controller, which will trigger a custom Session Flash (Bootstrap modal) with the data that we pass to the function. We can do this with Angular events emitter $emit and listener $on. Because our directive element is outside of MainController, it's scope is the $rootScope. This means that any event emitted by a child $scope will be intercepted if we use $on in the todoFlash directive.

Let's first define our event listener in our directive.

directives.js

(function(angular) {

angular.module('todoDirectives', [])
.directive('todoFlash', function() {
return {
restrict: 'AE',
replace: 'true',
templateUrl: 'views/error.html',
link: function(scope, element, attr) {
var e = $(element[0]);
var title = e.find('.modal-title');
var body = e.find('.modal-body');
scope.$on('flashevent', function(event, opts) {
title.html(opts.header);
body.html("<p>"+opts.message+"</p>");
e.modal('show');
})
}
}
})

})(angular);
In our link function, we get the modal title and body as wrapped jQuery objects. Note: Using jQuery with Angular is considered bad practice. Yet since we need to include jQuery anyway to power Bootstrap modals, it doesn't hurt to use it in this case.
We define an event listener with $on. It listens for flashevent and takes an opts object which must have opts.header and opts.message. Lastly, we trigger the modal.

Next, we write our controller function to trigger the Session Flash. Remember, we'll use $emit to trigger an event from emitting scope to all of its parent scopes. In this case, there's only one parent scope, the $rootScope.

controllers.js

$scope.flash = function(header, message) {
this.$emit('flashevent', {
header: header,
message: message
})
Since controllers.js is getting lengthy, I'm showing only the triggering function $scope.flash. We can call it from within our makeItem function with the this keyword.
$scope.makeItem = function() {
if (this.due === "yesterday") {
this.flash('Error', 'Can\'t add items due in the past');
return;
}
this.items.push({
task: this.task,
due: this.due
})
this.task = this.due = "";
}

Now, when we try to add to to-do item with a "Due" field of "yesterday", we see that a Session Flash is triggered:

That's it! We've made a Session Flash, and can call it from any scope by emitting a flashevent event. Look out for Part 3, coming soon, where we'll explore further customization and styling options.