Friday, 17 February 2017

What is Software Development and Its History


 AllCAD Services Private Limited  

First Steps

This part will be different from the History of the computer, no chronological travel trough software-land, but a collection of articles and assays on software.
Software has a long history and as far as the facts are known to us we will give them to you. When missing stories, data, or other information are shared to us they will be put on this site. If you have any comments of suggestions regarding this page or any other page please do not hesitate to contact us.
A simple question: "What is software?" A very simple answer is: Hardware you can touch, software you can't. But that is too simple indeed.
But when talking about software you talk about programming and programming languages. But about producing and selling the products made by programming (languages) as well.
There are over 300 different ("common") computer languages in existence, apart from the various dialects stemming from one of them. Most of them can be classified in definable groups, but others don’t belong to anything. Some because they are rather new or the use of them was or is never wide spread and only used by a small specialized professionals or groups of scientists requiring these dialects. This is often the case with a specific language that was designed for just one purpose, e.g. telecommunication or supercomputing.
Some languages are even dead languages, some others are revived and expanded upon again, and there are ones that constantly rejuvenate. In the latter case a programmer is sometimes wondering whether he or she is not just upgrading to a newer version but instead learning a complete new language.

How It All Started

It shouldn't be a big surprise that the creation or software also went in large but distinguishable steps. Compared with hardware there were fewer developments that went parallel or overlapping. In rare cases developments were reinvented sometimes because the development or invention was not published, even prohibited to be made public (war, secrecy acts etc.) or became known at the same time and after (legal)discussions the "other" party won the honors.
The earliest practical form of programming was probably done by Jaquard (1804, France). He designed a loom that performed predefined tasks through feeding punched cards into a reading contraption. This new technology allowed carpets and tissues to be manufactured with lower skills and even with fewer people. The little kid sitting under the loom changing rods and other things vanished. One single person could now handle a loom. That this met resistance from the weavers leaves no question. The same thing happened in England during the industrial revolution there. Even a movement came up called: Luddites (anti technology or just concerned citizens fighting for their bread?)

This picture shows the manufacturing
of punched cards for looms

The technology of punched cards will later be adapted by (IBM's) Recording and Tabulating Company to process data.
The situation was still a one on one game: a problem needed to be solved thus a machine was built. (Pascal, Babbage, Scheultz & Son) And when some sort of instruction was needed a sequence was designed or written and transferred to either cards or mechanical aids such as wires, gears, shafts actuators etc.. To call that programming? Well, according to our definition yes it was.
First there was Ada Lovelace, writing a rudimentary program (1843) for the Analytical Machine, designed by Charles Babbage in 1827, but the machine never came into operation.
Then there was George Boole (1815-1864), a British mathematician, who proved the relation between mathematics and logic with his algebra of logic (BOOLEAN algebra or binary logic) in 1847.
This meant a breakthrough for mathematics. Boole was the first to prove that logic is part of mathematics and not of philosophy.
A big step in thinking too.
But it will take one hundred years before this algebra of logic is put to work for computing.
John Von Neumann working at the Institute for Advanced Study developed in 1945 two important concepts that directly affected the path of computer programming languages:
The first concept became known as "shared-program technique" (7). This technique states that the actual computer hardware should be simple and not need to be hand-wired for each program. Instead, complex instructions should be used to control the simple hardware, allowing it to be reprogrammed much faster.(8)
The second concept was also extremely important to the development of programming languages. Von Neumann called it "conditional control transfer"(7) (www.softlord.com). This idea gave rise to the notion of subroutines, or small blocks of code that could be jumped to in any order, instead of a single set of chronologically ordered steps for the computer to take. The second part of the idea stated that computer code should be able to branch based on logical statements such as IF (expression) THEN, and looped such as with a FOR statement. "Conditional control transfer" gave rise to the idea of "libraries," which are blocks of code that can be reused over and over.(8)
the first draft on the EDVAC first draft on edvac

"What was first: software or hardware"
Frankly this is a matter of philosophy, or simpler: how you look at it.
 
(the following paragraphs are cited from http://www.princeton.edu/~ferguson/adw/programming_languages.shtml)
It took Claude Shannon (1916-2001) who wrote a thesis (A Mathematical Theory of Communication in the Bell System Technical Journal -1948) on how binary logic could be used in computing to complete the software concept of modern computing.
In 1949, a few years after Von Neumann's work, the language Short Code appeared . It was the first computer language for electronic devices and it required the programmer to change its statements into 0's and 1's by hand. Still, it was the first step towards the complex languages of today. In 1951, Grace Hopper wrote the first compiler, A-0. A compiler is a program that turns the language's statements into 0's and 1's for the computer to understand. This lead to faster programming, as the programmer no longer had to do the work by hand.(9)
In 1957, the first of the major languages appeared in the form of FORTRAN. Its name stands for FORmula TRANslating system. The language was designed at IBM for scientific computing. The components were very simple, and provided the programmer with low-level access to the computers innards. Today, this language would be considered restrictive as it only included IF, DO, and GOTO statements, but at the time, these commands were a big step forward. The basic types of data in use today got their start in FORTRAN, these included logical variables (TRUE or FALSE), and integer, real, and double-precision numbers.

Though FORTAN was good at handling numbers, it was not so good at handling input and output, which mattered most to business computing. Business computing started to take off in 1959, and because of this, COBOL was developed. It was designed from the ground up as the language for businessmen. Its only data types were numbers and strings of text. It also allowed for these to be grouped into arrays and records, so that data could be tracked and organized better. It is interesting to note that a COBOL program is built in a way similar to an essay, with four or five major sections that build into an elegant whole. COBOL statements also have a very English-like grammar, making it quite easy to learn. All of these features were designed to make it easier for the average business to learn and adopt it.

In 1958, John McCarthy of MIT created the LISt Processing (or LISP) language. It was designed for Artificial Intelligence (AI) research. Because it was designed for such a highly specialized field, its syntax has rarely been seen before or since. The most obvious difference between this language and other languages is that the basic and only type of data is the list, denoted by a sequence of items enclosed by parentheses. LISP programs themselves are written as a set of lists, so that LISP has the unique ability to modify itself, and hence grow on its own. The LISP syntax was known as "Cambridge Polish," as it was very different from standard Boolean logic (Wexelblat, 177) :
x V y - Cambridge Polish, what was used to describe the LISP program
OR(x,y) - parenthesized prefix notation, what was used in the LISP program
x OR y - standard Boolean logic
LISP remains in use today because its highly specialized and abstract nature.

The Algol language was created by a committee for scientific use in 1958. It's major contribution is being the root of the tree that has led to such languages as Pascal, C, C++, and Java. It was also the first language with a formal grammar, known as Backus-Naar Form or BNF (McGraw-Hill Encyclopedia of Science and Technology, 454). Though Algol implemented some novel concepts, such as recursive calling of functions, the next version of the language, Algol 68, became bloated and difficult to use (www.byte.com). This lead to the adoption of smaller and more compact languages, such as Pascal.

Pascal was begun in 1968 by Niklaus Wirth. Its development was mainly out of necessity for a good teaching tool. In the beginning, the language designers had no hopes for it to enjoy widespread adoption. Instead, they concentrated on developing good tools for teaching such as a debugger and editing system and support for common early microprocessor machines which were in use in teaching institutions.

Pascal was designed in a very orderly approach, it combined many of the best features of the languages in use at the time, COBOL, FORTRAN, and ALGOL. While doing so, many of the irregularities and oddball statements of these languages were cleaned up, which helped it gain users (Bergin, 100-101). The combination of features, input/output and solid mathematical features, made it a highly successful language. Pascal also improved the "pointer" data type, a very powerful feature of any language that implements it. It also added a CASE statement, that allowed instructions to to branch like a tree in such a manner:
CASE expression OF
       possible-expression-value-1:
              statements to execute...
       possible-expression-value-2:
              statements to execute...
END
Pascal also helped the development of dynamic variables, which could be created while a program was being run, through the NEW and DISPOSE commands. However, Pascal did not implement dynamic arrays, or groups of variables, which proved to be needed and led to its downfall (Bergin, 101-102). Wirth later created a successor to Pascal, Modula-2, but by the time it appeared, C was gaining popularity and users at a rapid pace.

C was developed in 1972 by Dennis Ritchie while working at Bell Labs in New Jersey. The transition in usage from the first major languages to the major languages of today occurred with the transition between Pascal and C. Its direct ancestors are B and BCPL, but its similarities to Pascal are quite obvious. All of the features of Pascal, including the new ones such as the CASE statement are available in C. C uses pointers extensively and was built to be fast and powerful at the expense of being hard to read. But because it fixed most of the mistakes Pascal had, it won over former-Pascal users quite rapidly.
Ritchie developed C for the new Unix system being created at the same time. Because of this, C and Unix go hand in hand. Unix gives C such advanced features as dynamic variables, multitasking, interrupt handling, forking, and strong, low-level, input-output. Because of this, C is very commonly used to program operating systems such as Unix, Windows, the MacOS, and Linux.

 In the late 1970's and early 1980's, a new programing method was being developed. It was known as Object Oriented Programming, or OOP. Objects are pieces of data that can be packaged and manipulated by the programmer. Bjarne Stroustroup liked this method and developed extensions to C known as "C With Classes." This set of extensions developed into the full-featured language C++, which was released in 1983.

C++ was designed to organize the raw power of C using OOP, but maintain the speed of C and be able to run on many different types of computers. C++ is most often used in simulations, such as games. C++ provides an elegant way to track and manipulate hundreds of instances of people in elevators, or armies filled with different types of soldiers. It is the language of choice in today's AP Computer Science courses.

In the early 1990's, interactive TV was the technology of the future. Sun Microsystems decided that interactive TV needed a special, portable (can run on many types of machines), language. This language eventually became Java. In 1994, the Java project team changed their focus to the web, which was becoming "the cool thing" after interactive TV failed. The next year, Netscape licensed Java for use in their internet browser, Navigator. At this point, Java became the language of the future and several companies announced applications which would be written in Java, none of which came into use.

Though Java has very lofty goals and is a text-book example of a good language, it may be the "language that wasn't". It has serious optimization problems, meaning that programs written in it run very slowly. And Sun has hurt Java's acceptance by engaging in political battles over it with Microsoft. But Java may wind up as the instructional language of tomorrow as it is truly object-oriented and implements advanced techniques such as true portability of code and garbage collection.

Visual Basic is often taught as a first programming language today as it is based on the BASIC language developed in 1964 by John Kemeny and Thomas Kurtz. BASIC is a very limited language and was designed for non-computer science people. Statements are chiefly run sequentially, but program control can change based on IF..THEN, and GOSUB statements which execute a certain block of code and then return to the original point in the program's flow.

Microsoft has extended BASIC in its Visual Basic (VB) product. The heart of VB is the form, or blank window on which you drag and drop components such as menus, pictures, and slider bars. These items are known as "widgets." Widgets have properties (such as its color) and events (such as clicks and double-clicks) and are central to building any user interface today in any language. VB is most often used today to create quick and simple interfaces to other Microsoft products such as Excel and Access without needing a lot of code, though it is possible to create full applications with it.

Perl has often been described as the "duct tape of the Internet," because it is most often used as the engine for a web interface or in scripts that modify configuration files. It has very strong text matching functions which make it ideal for these tasks. Perl was developed by Larry Wall in 1987 because the Unix sed and awk tools (used for text manipulation) were no longer strong enough to support his needs. Depending on whom you ask, Perl stands for Practical Extraction and Reporting Language or Pathologically Eclectic Rubbish Lister.

Programming languages have been under development for years and will remain so for many years to come. They got their start with a list of steps to wire a computer to perform a task. These steps eventually found their way into software and began to acquire newer and better features. The first major languages were characterized by the simple fact that they were intended for one purpose and one purpose only, while the languages of today are differentiated by the way they are programmed in, as they can be used for almost any purpose. And perhaps the languages of tomorrow will be more natural with the invention of quantum and biological computers.
<end quote> 
Also the hardware needed to make jumps ahead like the folowing:
  • It took Zuse to create the first binary programmable computer, relay based.
  • The Bomba, originally built by Polish engineers to crack the Enigma code, pushed the envelop again
  • The colossus built by people from Bletchley Park (near London, UK) for the same purpose
  • Atanasov and Berry designed the ABC computer, a binary computer, as Zuse's was, but now 100% electronic.
  • And not to forget the ENIAC by Eckert and Mauchly and a team made up of many others
Now things were in place to start off with the information age.

Enter the Information Age

In the beginning of the so called "Information Age" computers were programmed by "programming" direct instructions into it. This was done by setting switches or making connections to different logical units by wires (circuitry).
(1)
Two women wiring the right side of the ENIAC with a new program
(US Army photo, from archives of the ARL Technical library, courtesy of Mike Muuss)
Programming like this was nothing else but rewiring these huge machines in order to use all the options, possibilities and calculations. Reprogramming always meant rewiring.
In that way calculations needed days of preparations, handling thousands of wires, resetting switches, plugs etc. (in the most extreme case that is). And the programmed calculation itself just took a few minutes. If the "programming" of wiring did not have a wrong connection, the word bug was not in used yet, for programming errors.
The coding panels very much looked like that a few telephone switchboards hustled together, and in fact many parts actually came from switch boards.
With the invention of vacuum tubes, along with many other inventions, much of the rewiring belonged to the past. The tubes replaced the slow machines based on relays.

When the transistor was invented this again replaced a technology: vacuum tubes.
When Shannon reinvented or better rediscovered the binary calculus in 1948 and indicated how that could be used for computing a revolution started. The race was on!

Programming the new tools (or toys?)
Programming the first binary computer was still not an easy task and much prone to mistakes. First programming was done by typing in 1's or 0's that were stored on different information carriers. Like paper tapes, punched hole cards, hydrogen delay lines (sound or electric pulse) and later magnetic drums and much later magnetic and optical discs.
By storing these 0's and 1's on a carrier (first used by Karl Suze's X1 in 1938) it was possible to have the computer read the data on any later time. But mis typing a single zero or one meant a disaster because all coding (instructions) should absolutely be on the right place and in the right order in memory. This technology was called absolute addressing.
An example:
1010010101110101011
If this is a sequence for switches it means switch one on, switch two off etc. etc.  
In simple language:
Panel1function: enter house
Switch 01open the door
Switch 11put the lights on
Switch 20close the door (please)
In fact the protocols for programming the machines in this way looked very much like that.
In the early 50's programmers started to let the machines do a part of the job. This was called automatic coding and made live a lot easier for the early programmers.

Soon the next step was to have the program to select the proper memory address in stead of using absolute addressing.
The next development was to combine groups of instruction into so called words and abbreviations were thought up called: opcodes (Hopper 1948)

Machine Language
Opcode works like a shorthand and represents as said a group of machine instructions. The opcode is translated by another program into zero's and one's, something a machine could translate into instructions.
But the relation is still one to one: one code to one single instruction. However very basically this is already a programming language. It was called: assembly language.
An example:
LabelOpcodeRegister
CALC:STOR1, HELP0
 STOR2, HELP2
 LDR3, HELP1
 ADDR3, HELP2
 LDR4, HELP1
 SUBR4, HELP2
 RSRSP, 0
HELP1:DS2
HELP2:DS2
                           
This piece of assembly code calculates the difference between two numbers.

Subroutines
Soon after developing machine languages and the first crude programming languages began to appear the danger of inextricable and thus unreadable coding became apparent. Later this messy programming was called: "spaghetti code".
One important step in unraveling or preventing spaghetti code was the development of subroutines. And it needed Maurice Wilkes, when realizing that "a good part of the remainder of his life was going to be spent in finding errors in ... programs", to develop the concept of subroutines in programs to create reusable modules. Together with Stanley Gill and David Wheeler he produced the first textbook on "The Preparation of Programs for an Electronic Digital Computer".(6)
The formalized concept of software development (not named so for another decade) had its beginning in 1951.
Below is an example of how subroutines would work.
Start of program
the main "menu"



first subroutine

back to the main menu
second subroutine
with a parameter (contents of what to print)


back to procedure: main
Begin program;
Main;
Printf ("Hello World");
DoSomethingElse()
Printf ("Hello World");
(end of program)
Function DoSomethingElse;
Add two numbers;
Return OK
Function Printf(what_to_print)
Open channel to printer interface;
Initialize printer;
Send "what_to_print" to printer;
Send page feed to printer;
Close printer interface;
Return OK

This program would print "Hello World" twice on two different pages.
By re-using the Printf subroutine a possible error in this routine would show up only once. An enormous advantage when looking for errors. Off course the Open, Initialize, Send, and Close "commands" in this Printf function are also subroutines.

Fortran
The next big step in programming began when an IBM team under John W. Backus created FORTRAN - FORmula TRANslator 1952. It could only be used on their own machine, the: IBM 704. But later versions for other machines, and platforms were sold soon after. Until long past 1960 different CPU's required an other kind instruction set to add a number, thus for each different machine a different compiler was needed. Typically the manual came years later in 1957!
Rewiring of machines to reprogram them now definitely belonged to the past!
Programming language
FORTRAN soon became called a programming language. So why calling a set of some predefined instructions a programming language?
Because some characteristics of a language are met:
  • It must have a vocabulary - list of words
  • It must have a grammar - or syntax
  • It must be unique, both in words and in context
All the above criteria were easily met for this - strictly defined- set of computer instructions.
An example:
Let's presume communication with a computer can be accomplished. Then how would you tell it to add two numbers in simple terms?
humancomputer
Add 2 and 2 
Show me the answerprint 2+2
Depending on what (dialect of) computer language you use it could look different:
humancomputer
Add 2 and 2answer := 2+2;
Show me the answerprintf ("%d\n", answer);
And by the time when Cobol, Common Business Oriented Language, was published in 1960 by the Codasyl committee, (Hopper was a member) the term Computer Language was a fact.
In the meantime hardware developments raced literally ahead.
Already computers were connected to teletype machines to expedite the entry of programs. In the late 1960's the first video interfaces were connected. The network was invented. And floppy disks, harddrives etc. made live for programmers a lot easier.
As mentioned you could not simply run FORTRAN on any machine. It had to be rewritten for each particular machine if the type of processor was different. In in that early days ALL types were different. This did not promote the development of programming at all!

Enter "C"
C came into being in the years 1969-1973 and was developed by Dennis Richey and David Kerningham both working at the Bell laboratories.(3)
And the magic word was portability.
Parallel at the development of computer languages, Operating Systems (OS) were developed. These were needed because to create programs and having to write all machine specific instructions over and over again was a "waste of time" job.
So by introducing the OS 'principle' almost all input and output tasks were taken over by the OS.
Such as:
  • writing data to and from memory,
  • saving data on disks,
  • writing data to screens and printers,
  • starting tapes,
  • refreshing memory,
  • scheduling specific tasks
  • etcetera, etcetera.
As the common computer languages had trouble to be translated from one machine to another the OS's had to take the same hurdle every time a new machine was developed.
The need ad pressure for a common portable language was enormous.
There were some unsuccessful projects aimed to solve this problem, like Multics, a joint venture of MIT, General Electric, and Bell Labs. And other developments at DOD's in different countries. But they all came either too late or became too complex to succeed.
But the demise of Multics inspired Dennis Ritchie and Brian Kernigham to develop C in 1972. This was and still is a very strict language that stayed close enough to the machine's internal logic and structure. If you were allowed to say that. This new language was reasonable well to read and understand by humans. And because of this combination the language is fast, compact and became very popular amongst system programmers and commercial software manufacturers.
With that language they also developed UNIX, a generic operating system.
The power of C was that the language had a small language base (vocabulary) but leaned heavily on what they called libraries. Libraries contain machine specific instructions to perform tasks, like the OS does. These libraries were the only parts that had to be redesigned for different machines, or processor families. But, and that was C's strength, the programming interface/language remained the same. Portability was born. Sourcecode could be reused, only to be recompiled when it had to run on other machines.
A classic example of C, printing "Hello World" on your screen:
 
/* helloworld.c */
main()
{
printf('Hello World\n");
}
In another chapter this routine will be shown to make the various differences in language visual.
Soon other language manufacturers sprang on the bandwagon and the software industry leaped ahead. The industry took of like a rocket!

For More Details About Please visit our website at www.allcadsercvices.com

Thursday, 16 February 2017

Web Application Development using Angular.Js

Choosing the right tool for the right purpose goes a long way, especially when it comes to building modern web applications. A lot of us are familiar with AngularJS and how easy it makes developing robust web application front-ends. Although many will argue against the use of this popular web framework, it certainly has plenty to offer and can be an appropriate choice for a wide array of needs. On the other hand, the components that you use on the back-end will dictate a lot about the web application’s performance, as they have influence on the overall user experience. Play is a high velocity web framework for Java and Scala. It is based on a lightweight, stateless, web-friendly architecture and follows MVC patterns and principles similar to Rails and Django.
web applications with angularjs and play framework
AllCAD Services Private Limited
In this article, we will take a look at how we can use AngularJS and Play to build a simple blog application with a basic authentication mechanism and the ability to make posts and comments. AngularJS, with some Twitter Bootstrap goodies, will allow us to power a single-page application experience on top of a Play based REST API back-end.

Web Applications - Getting Started

AngularJS Application Skeleton

AngularJS and Play apps will reside in client and server directories accordingly. For now, we shall create the “client” directory.
mkdir -p blogapp/client
To create an AngularJS application skeleton, we will use Yeoman - an amazing scaffolding tool. Installing Yeoman is easy. Using it to scaffold a simple skeletal AngularJS application is probably even easier:
cd blogapp/client
yo angular
Running the second command will be followed by a few options that you need to pick from. For this project, we do not need “Sass (with Compass)”. We will need Boostrap along with the following AngularJS plugins:
  • angular-animate.js
  • angular-cookies.js
  • angular-resource.js
  • angular-route.js
  • angular-sanitize.js
  • angular-touch.js
At this point, once you finalize your selections, you will start seeing NPM and Bower output on your terminal. When the downloads are complete and the packages have been installed, you will have an AngularJS application skeleton ready to be used.

Play Framework Application Skeleton

The official way of creating a new Play application involves the use of the tool Type safe Activator. Before you can use it, you have to download and install it on your computer. If you are on Mac OS and use Homebrew, you can install this tool with a single line of command:
brew install typesafe-activator 
Creating a Play application from command line is super easy:
cd blogapp/
activator new server play-java
cd server/

Importing to an IDE

To import the application in an IDE such as Eclipse or IntelliJ, you need to “eclipsify” or “idealize” your application. To do that, run the following command:
activator
Once you see a new prompt, type either “eclipse” or “idea” and hit enter to prepare the application code for Eclipse or IntelliJ, respectively.
For brevity, we will only cover the process of importing the project to IntelliJ in this article. The process of importing it to Eclipse should be equally simple. To import the project to IntelliJ, start by activating the “Project from existing sources…” option found under “File -> New”. Next, select your build.sbt file and click “OK”. Upon clicking “OK” again on the next dialog, IntelliJ should start importing your Play application as an SBT project.
Typesafe Activator also comes with a graphical user interface, which you can use to create this skeletal application code.
Now that we have imported our Play application into IntelliJ, we should also import our AngularJS application into the workspace. We can import it either as a separate project or as a module to the existing project where Play application resides.
Here, we will import the Angular application as a module. Under the “File” menu, we will select the option “New -> Module From Existing Sources…”. From the dialog, we will choose the “client” directory and click on “OK”. On the next two screens, click on “Next” and “Finish”, respectively.

Spawning Local Servers

At this point, it should be possible to start the AngularJS application as a Grunt task from the IDE. Expand your client folder and right click on Gruntfile.js. In the pop-up menu select “Show Grunt Tasks”. A panel labelled “Grunt” will appear with a list of tasks:

To start serving the application, double click on “serve”. This should immediately open your default web browser and point it to a localhost address. You should see a stub AngularJS page with Yeoman’s logo on it.
Next, we need to launch our back-end application server. Before we can proceed, we must address a couple of issues:
  1. By default, both the AngularJS application (bootstrapped by Yeoman) and the Play application tries to run on port 9000.
  2. In production, both applications will likely be run under one domain, and we will probably use Nginx to route the requests accordingly. But in development mode, when we change the port number of one of these applications, web browsers will treat them as if they are running on different domains.
To work around both of these issues, all we need to do is use a Grunt proxy so that all AJAX requests to the Play application are peroxided. With this, in essence both of these application servers will be available at the same apparent port number.
Let us first change the port number of the Play application server to 9090. To do this, open the “Run/Debug Configurations” window by clicking on “Run -> Edit Configurations”. Next, change the port number in the field “Url To Open”. Click on “OK” to approve this change and close the window. Clicking on the “Run” button should start the dependency resolution process - logs of this process will start appearing.

Once it is done, you can navigate to http://localhost:9090 on your web browser, and in a few seconds you should be able to see your Play application. To configure a Grunt proxy, we first need to install a small Node.js package using NPM:
cd blogapp/client
npm install grunt-connect-proxy --save-dev
Next we need to tweak our Gruntfile.js. In that file, locate the “connect” task, and insert the “proxies” key/value after it:
 proxies: [
   {
     context: '/app', // the context of the data service
     host: 'localhost', // wherever the data service is running
     port: 9090, // the port that the data service is running on
     changeOrigin: true
   }
 ],
Grunt will now proxy all requests to “/app/*” to the back-end Play application. This will save us from having to whitelist every call to the back-end. Furthermore, we also need to tweak our livereload behavior:
livereload: {
 options: {
   open: true,

   middleware: function (connect) {
     var middlewares = [];

     // Setup the proxy
     middlewares.push(require('grunt-connect-proxy/lib/utils').proxyRequest);

     // Serve static files
     middlewares.push(connect.static('.tmp'));
     middlewares.push(connect().use(
       '/bower_components',
       connect.static('./bower_components')
     ));
     middlewares.push(connect().use(
       '/app/styles',
       connect.static('./app/styles')
     ));
     middlewares.push(connect.static(appConfig.app));

     return middlewares;
   }
 }
}, 
Finally, we need to add a new dependency “’configureProxies:server” to the “serve” task:
grunt.registerTask('serve', 'Compile then start a connect web server', function (target) {
 if (target === 'dist') {
   return grunt.task.run(['build', 'connect:dist:keepalive']);
 }

 grunt.task.run([
   'clean:server',
   'wiredep',
   'concurrent:server',
   'autoprefixer:server',
   'configureProxies:server',
   'connect:livereload',
   'watch'
 ]);
});
Upon restarting Grunt, you should notice the following lines in your logs indicating that the proxy is running:
Running "autoprefixer:server" (autoprefixer) task
File .tmp/styles/main.css created.

Running "configureProxies:server" (configureProxies) task

Running "connect:livereload" (connect) task
Started connect web server on http://localhost:9000

Creating a Sign-up Form

We will begin by creating a sign-up form for our blog application. This will also allow us to verify that everything is working as it should. We can use Yeoman to create a Sign-up controller and view in AngularJS:
yo angular:controller signup
yo angular:view signup
Next we should update routing of our application to reference this newly created view, and remove the redundant auto-generated “about” controller and view. From within the file “app/scripts/app.js”, remove references to “app/scripts/controllers/about.js” and “app/views/about.html”, leaving it with:
.config(function ($routeProvider) {
 $routeProvider
   .when('/', {
     templateUrl: 'views/main.html',
     controller: 'MainCtrl'
   })
   .when('/signup', {
     templateUrl: 'views/signup.html',
     controller: 'SignupCtrl'
   })
   .otherwise({
     redirectTo: '/'
   });
Similarly, update the “app/index.html” file to remove the redundant links, and add a link to the signup page:
<div class="collapse navbar-collapse" id="js-navbar-collapse">
   <ul class="nav navbar-nav">
     <li class="active"><a href="#/">Home</a></li>
     <li><a ng-href="#/signup">Signup</a></li>
   </ul>
 </div>
</div>
Also, remove the script tag for “about.js”:
<!-- build:js({.tmp,app}) scripts/scripts.js -->
       <script src="scripts/app.js"></script>
       <script src="scripts/controllers/main.js"></script>
       <script src="scripts/controllers/signup.js"></script>
<!-- endbuild -->
</body>
</html>
Next, add a form to our “signup.html” file:
<form name="signupForm" ng-submit="signup()" novalidate>
 <div>
   <label for="email">Email</label>
   <input name="email" class="form-control" type="email" id="email" placeholder="Email"
          ng-model="email">
   </div>
 <div>
   <label for="password">Password</label>
   <input name="password" class="form-control" type="password" id="password"
          placeholder="Password" ng-model="password">

 </div>
 <button type="submit" class="btn btn-primary">Sign up!</button>
</form>
We need to make the form be processed by the Angular controller. It is worth noting that we do not need to specifically add the “ng-controller” attribute in our views, as our routing logic in “app.js” fires up a controller automatically before our view is loaded. All we have to do to wire this form up is have a proper “signup” function defined in $scope. This should be done in the “signup.js” file:
angular.module('clientApp')
   .controller('SignupCtrl', function ($scope, $http, $log) {
     $scope.signup = function() {
       var payload = {
         email : $scope.email,
         password : $scope.password
       };

       $http.post('app/signup', payload)
           .success(function(data) {
             $log.debug(data);
           });
     };
   });
Now let us open Chrome developer console, switch to the “Network” tab, and try to submit the signup form.

We’ll see that the Play back-end naturally replies with an “Action not found” error page. This is expected as it has not been implemented yet. But what it also means is that our Grunt proxy setup is working correctly!
Next, we are going to add an “Action” which is essentially a method in the Play application controller. In the class “Application” in “app/controllers” package, add a new method “signup”:
public static Result signup() {
 return ok("Success!");
}
Now open the file “conf/routes” and add the following line:
POST        /app/signup          controllers.Application.signup
Finally, we return to our web browser, http://localhost:9000/#/signup. Clicking on the “Submit” button this time should yield something different:

You should be seeing the hard-coded value returned, the one we wrote in the signup method. If that is the case, we are ready to move on as our development environment is ready and is working for both the Angular and Play applications.

Defining Ebean Models in Play

Before defining models, let us first pick a data store. In this article, we will use H2 in-memory database. To enable that, find and commencement the following lines in the file “application.conf”:
db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:mem:play"
db.default.user=sa
db.default.password=""
...
ebean.default="models.*"
And add the following line:
applyEvolutions.default=true
Our blog domain model is rather simple. First of all, we have users that may create posts and then each post can be commented on by any signed in user. Let’s create our Eben Models.

User

// User.java

@Entity
public class User extends Model {

 @Id
 public Long id;

 @Column(length = 255, unique = true, nullable = false)
 @Constraints.MaxLength(255)
 @Constraints.Required
 @Constraints.Email
 public String email;

 @Column(length = 64, nullable = false)
 private byte[] shaPassword;

 @OneToMany(cascade = CascadeType.ALL)
 @JsonIgnore
 public List<BlogPost> posts;

 public void setPassword(String password) {
   this.shaPassword = getSha512(password);
 }

 public void setEmail(String email) {
   this.email = email.toLowerCase();
 }

 public static final Finder<Long, User> find = new Finder<Long, User>(
     Long.class, User.class);

 public static User findByEmailAndPassword(String email, String password) {
   return find
       .where()
       .eq("email", email.toLowerCase())
       .eq("shaPassword", getSha512(password))
       .findUnique();
 }

 public static User findByEmail(String email) {
   return find
       .where()
       .eq("email", email.toLowerCase())
       .findUnique();
 }

 public static byte[] getSha512(String value) {
   try {
     return MessageDigest.getInstance("SHA-512").digest(value.getBytes("UTF-8"));
   }
   catch (NoSuchAlgorithmException e) {
     throw new RuntimeException(e);
   }
   catch (UnsupportedEncodingException e) {
     throw new RuntimeException(e);
   }
 }
}

BlogPost

// BlogPost.java

@Entity
public class BlogPost extends Model {

 @Id
 public Long id;

 @Column(length = 255, nullable = false)
 @Constraints.MaxLength(255)
 @Constraints.Required
 public String subject;

 @Column(columnDefinition = "TEXT")
 @Constraints.Required
 public String content;

 @ManyToOne
 public User user;

 public Long commentCount;

 @OneToMany(cascade = CascadeType.ALL)
 public List<PostComment> comments;

 public static final Finder<Long, BlogPost> find = new Finder<Long, BlogPost>(
     Long.class, BlogPost.class);

 public static List<BlogPost> findBlogPostsByUser(final User user) {
   return find
       .where()
       .eq("user", user)
       .findList();
 }

 public static BlogPost findBlogPostById(final Long id) {
   return find
       .where()
       .eq("id", id)
       .findUnique();
 }

}
Like what you're reading?
Get the latest updates first.

PostComment

// PostComment.java

@Entity
public class PostComment extends Model {

 @Id
 public Long id;

 @ManyToOne
 @JsonIgnore
 public BlogPost blogPost;

 @ManyToOne
 public User user;

 @Column(columnDefinition = "TEXT")
 public String content;

 public static final Finder<Long, PostComment> find = new Finder<Long, PostComment>(
     Long.class, PostComment.class);

 public static List<PostComment> findAllCommentsByPost(final BlogPost blogPost) {
   return find
       .where()
       .eq("post", blogPost)
       .findList();
 }

 public static List<PostComment> findAllCommentsByUser(final User user) {
   return find
       .where()
       .eq("user", user)
       .findList();
 }

}

Real Signup Action

Now let’s create our first real action, allowing the users to sign up:
// Application.java

public static Result signup() {
 Form<SignUp> signUpForm = Form.form(SignUp.class).bindFromRequest();

 if ( signUpForm.hasErrors()) {
   return badRequest(signUpForm.errorsAsJson());
 }
 SignUp newUser =  signUpForm.get();
 User existingUser = User.findByEmail(newUser.email);
 if(existingUser != null) {
   return badRequest(buildJsonResponse("error", "User exists"));
 } else {
   User user = new User();
   user.setEmail(newUser.email);
   user.setPassword(newUser.password);
   user.save();
   session().clear();
   session("username", newUser.email);

   return ok(buildJsonResponse("success", "User created successfully"));
 }
}

public static class UserForm {
 @Constraints.Required
 @Constraints.Email
 public String email;
}

public static class SignUp extends UserForm {
 @Constraints.Required
 @Constraints.MinLength(6)
 public String password;
}

private static ObjectNode buildJsonResponse(String type, String message) {
  ObjectNode wrapper = Json.newObject();
  ObjectNode msg = Json.newObject();
  msg.put("message", message);
  wrapper.put(type, msg);
  return wrapper;
}
Note that the authentication used in this app is very basic, and is not recommended for production use.
The interesting part is that we are using Play forms to handle signup forms. We set a couple constrains on our Sign Up form class. Validation will be done for us automatically without need for explicit validation logic.
If we get back to our AngularJS application in the web browser and click on “Submit” again, we will see that the server now responds with an appropriate error - that these fields are required.

Handling Server Errors in AngularJS

So we are getting an error from server, but the application user has no idea what’s going on. The least we can do is to display the error to our user. Ideally, we would need to understand what kind of error we’re getting and display a user-friendly message. Let’s create a simple alert service that will help us display the error.
First, we need to generate a service template with Yeoman:
yo angular:service alerts
Next, add this code to “alerts.js”:
angular.module('clientApp')
   .factory('alertService', function($timeout) {

     var ALERT_TIMEOUT = 5000;

     function add(type, msg, timeout) {

       if (timeout) {
         $timeout(function(){
           closeAlert(this);
         }, timeout);
       } else {
         $timeout(function(){
           closeAlert(this);
         }, ALERT_TIMEOUT);
       }

       return alerts.push({
         type: type,
         msg: msg,
         close: function() {
           return closeAlert(this);
         }
       });
     }

     function closeAlert(alert) {
       return closeAlertIdx(alerts.indexOf(alert));
     }

     function closeAlertIdx(index) {
       return alerts.splice(index, 1);
     }

     function clear(){
       alerts = [];
     }

     function get() {
       return alerts;
     }

     var service = {
           add: add,
           closeAlert: closeAlert,
           closeAlertIdx: closeAlertIdx,
           clear: clear,
           get: get
         },
         alerts = [];

     return service;
   }
);
Now, let’s create a separate controller responsible for alerts:
yo angular:controller alerts
angular.module('clientApp')
 .controller('AlertsCtrl', function ($scope, alertService) {
     $scope.alerts = alertService.get();
 });
Now we need to actually show nice Bootstrap error messages. The easiest way is to use Angular UI. We can use Bower to install it:
bower install angular-bootstrap --save
In your “app.js” append Angular UI module:
angular
   .module('clientApp', [
     'ngAnimate',
     'ngCookies',
     'ngResource',
     'ngRoute',
     'ngSanitize',
     'ngTouch',
     'ui.bootstrap'
   ])
Let’s add alert directive to our “index.html” file:
<div class="container">
 <div ng-controller="AlertsCtrl">
   <alert ng-repeat="alert in alerts" type="{{alert.type}}" close="alert.close()">{{ alert.msg }}</alert>
 </div>
 <div ng-view=""></div>
</div>
Finally, we need to update SignUp controller:
angular.module('clientApp')
   .controller('SignupCtrl', function ($scope, $http, $log, alertService, $location, userService) {

     $scope.signup = function() {
       var payload = {
         email : $scope.email,
         password : $scope.password
       };

       $http.post('app/signup', payload)
           .error(function(data, status) {
             if(status === 400) {
               angular.forEach(data, function(value, key) {
                 if(key === 'email' || key === 'password') {
                   alertService.add('danger', key + ' : ' + value);
                 } else {
                   alertService.add('danger', value.message);
                 }
               });
             }
             if(status === 500) {
               alertService.add('danger', 'Internal server error!');
             }
           })
 
     };
   });
Now if we send the empty form again we will see errors displayed above the form:
Now that errors are handled, we need to do something when user signup is successful. We can redirect the user to a dashboard page where he can add posts. But first, we must create it:
yo angular:view dashboard
yo angular:controller dashboard
Modify “signup.js” controller signup method so that on success it redirects the user:
angular.module('clientApp')
   .controller('SignupCtrl', function ($scope, $http, $log, alertService, $location) {
// ..
.success(function(data) {
 if(data.hasOwnProperty('success')) {
   $location.path('/dashboard');
 }
});
Add a new route in “apps.js”:
.when('/dashboard', {
 templateUrl: 'views/dashboard.html',
 controller: 'DashboardCtrl'
})
We also need to track if the user is logged in. Let us create a separate service for that:
yo angular:service user
// user.js

angular.module('clientApp')
   .factory('userService', function() {
     var username = '';

     return {
       username : username
     };
   });
And also modify the signup controller to set the user to one who just registered:
.success(function(data) {
 if(data.hasOwnProperty('success')) {
   userService.username = $scope.email;
   $location.path('/dashboard');;
 }
});
Before we add the main functionality of adding posts, let’s take care of some other important features such as ability to login and logout, displaying user information on the dashboard, and also adding authentication support in the back-end.

Basic Authentication

Let’s jump over to our Play application and implement the login and logout actions. Add theses lines to “Application.java”:
public static Result login() {
 Form<Login> loginForm = Form.form(Login.class).bindFromRequest();
 if (loginForm.hasErrors()) {
   return badRequest(loginForm.errorsAsJson());
 }
 Login loggingInUser = loginForm.get();
 User user = User.findByEmailAndPassword(loggingInUser.email, loggingInUser.password);
 if(user == null) {
   return badRequest(buildJsonResponse("error", "Incorrect email or password"));
 } else {
   session().clear();
   session("username", loggingInUser.email);

   ObjectNode wrapper = Json.newObject();
   ObjectNode msg = Json.newObject();
   msg.put("message", "Logged in successfully");
   msg.put("user", loggingInUser.email);
   wrapper.put("success", msg);
   return ok(wrapper);
 }
}


public static Result logout() {
 session().clear();
 return ok(buildJsonResponse("success", "Logged out successfully"));
}

public static Result isAuthenticated() {
 if(session().get("username") == null) {
   return unauthorized();
 } else {
   ObjectNode wrapper = Json.newObject();
   ObjectNode msg = Json.newObject();
   msg.put("message", "User is logged in already");
   msg.put("user", session().get("username"));
   wrapper.put("success", msg);
   return ok(wrapper);
 }
}

public static class Login extends UserForm {
 @Constraints.Required
 public String password;
}
Next let’s add the ability to allow particular back-end calls only to authenticated users. Create “Secured.java” with the following code:
public class Secured extends Security.Authenticator {

 @Override
 public String getUsername(Context ctx) {
   return ctx.session().get("username");
 }

 @Override
 public Result onUnauthorized(Context ctx) {
   return unauthorized();
 }
}
We will use this class later to protect new actions. Next, we should tweak our AngularJS application main menu so that it displays the username and logout links. For that, we need to create controller:
yo angular:controller menu
// menu.js

angular.module('clientApp')
   .controller('MenuCtrl', function ($scope, $http, userService, $location) {
     $scope.user = userService;

     $scope.logout = function() {
       $http.get('/app/logout')
           .success(function(data) {
             if(data.hasOwnProperty('success')) {
               userService.username = '';
               $location.path('/login');
             }
           });
     };

     $scope.$watch('user.username', function (newVal) {
       if(newVal === '') {
         $scope.isLoggedIn = false;
       } else {
         $scope.username = newVal;
         $scope.isLoggedIn = true;
       }
     });
   });
We also need a view and a controller for the login page:
yo angular:controller login
yo angular:view login
<!-- login.html -->

<form name="loginForm" ng-submit="login()" novalidate>
 <div>
   <label for="email">Email</label>
   <input name="email" class="form-control" type="email" id="email" placeholder="Email"
          ng-model="email">
 </div>
 <div>
   <label for="password">Password</label>
   <input name="password" class="form-control" type="password" id="password"
          placeholder="Password" ng-model="password">

 </div>
 <button type="submit" class="btn btn-primary">Log in</button>
</form>
// login.js

angular.module('clientApp')
   .controller('LoginCtrl', function ($scope, userService, $location, $log, $http, alertService) {

     $scope.isAuthenticated = function() {
       if(userService.username) {
         $log.debug(userService.username);
         $location.path('/dashboard');
       } else {
         $http.get('/app/isauthenticated')
             .error(function() {
               $location.path('/login');
             })
             .success(function(data) {
               if(data.hasOwnProperty('success')) {
                 userService.username = data.success.user;
                 $location.path('/dashboard');
               }
             });
       }
     };

     $scope.isAuthenticated();

     $scope.login = function() {

       var payload = {
         email : this.email,
         password : this.password
       };

       $http.post('/app/login', payload)
           .error(function(data, status){
             if(status === 400) {
               angular.forEach(data, function(value, key) {
                 if(key === 'email' || key === 'password') {
                   alertService.add('danger', key + ' : ' + value);
                 } else {
                   alertService.add('danger', value.message);
                 }
               });
             } else if(status === 401) {
               alertService.add('danger', 'Invalid login or password!');
             } else if(status === 500) {
               alertService.add('danger', 'Internal server error!');
             } else {
               alertService.add('danger', data);
             }
           })
           .success(function(data){
             $log.debug(data);
             if(data.hasOwnProperty('success')) {
               userService.username = data.success.user;
               $location.path('/dashboard');
             }
           });
     };
   });
Next we tweak the menu so that it can display user data:
<!-- index.html -->

<div class="collapse navbar-collapse" id="js-navbar-collapse" ng-controller="MenuCtrl">
 <ul class="nav navbar-nav pull-right" ng-hide="isLoggedIn">
   <li><a ng-href="/#/signup">Sign up!</a></li>
   <li><a ng-href="/#/login">Login</a></li>
 </ul>
 <div class="btn-group pull-right acc-button" ng-show="isLoggedIn">
   <button type="button" class="btn btn-default">{{ username }}</button>
   <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"
           aria-expanded="false">
     <span class="caret"></span>
     <span class="sr-only">Toggle Dropdown</span>
   </button>
   <ul class="dropdown-menu" role="menu">
     <li><a ng-href="/#/dashboard">Dashboard</a></li>
     <li class="divider"></li>
     <li><a href="#" ng-click="logout()">Logout</a></li>
   </ul>
 </div>
</div>
Now if you log in into the application, you should be able to see the following screen:

Adding Posts

Now that we have basic signup and authentication mechanisms in place, we can get down to implementing the posting functionality. Let’s add a new view and controller for adding posts.
yo angular:view addpost
<!-- addpost.html -->

<form name="postForm" ng-submit="post()" novalidate>
 <div>
   <label for="subject">Subject</label>
   <input name="subject" class="form-control" type="subject" id="subject" placeholder="Subject"
          ng-model="subject">
 </div>
 <div>
   <label for="content">Post</label>
   <textarea name="content" class="form-control" id="content" placeholder="Content"
             ng-model="content"></textarea>
 </div>

 <button type="submit" class="btn btn-primary">Submit post</button>
</form>
yo angular:controller addpost
// addpost.js

angular.module('clientApp')
 .controller('AddpostCtrl', function ($scope, $http, alertService, $location) {

   $scope.post = function() {
     var payload = {
       subject : $scope.subject,
       content: $scope.content
     };
     $http.post('/app/post', payload)
         .error(function(data, status) {
           if(status === 400) {
             angular.forEach(data, function(value, key) {
               if(key === 'subject' || key === 'content') {
                 alertService.add('danger', key + ' : ' + value);
               } else {
                 alertService.add('danger', value.message);
               }
             });
           } else if(status === 401) {
             $location.path('/login');
           } else if(status === 500) {
             alertService.add('danger', 'Internal server error!');
           } else {
             alertService.add('danger', data);
           }
         })
         .success(function(data) {
           $scope.subject = '';
           $scope.content = '';
           alertService.add('success', data.success.message);
         });
   };
 });
Then we update “app.js” to include:
.when('/addpost', {
 templateUrl: 'views/addpost.html',
 controller: 'AddpostCtrl'
})
Next, we modify “index.html” to add a link for our “addpost” view on the dashboard menu:
<ul class="dropdown-menu" role="menu">
  <li><a ng-href="/#/dashboard">Dashboard</a></li>
  <li><a ng-href="/#/addpost">Add post</a></li>
  <li class="divider"></li>
  <li><a href="#" ng-click="logout()">Logout</a></li>
</ul>
Now on the Play application side, let’s create a new controller Post with addPost method:
// Post.java

public class Post extends Controller {

public static Result addPost() {
 Form<PostForm> postForm = Form.form(PostForm.class).bindFromRequest();

 if (postForm.hasErrors()) {
   return badRequest(postForm.errorsAsJson());
 } else {
   BlogPost newBlogPost = new BlogPost();
   newBlogPost.commentCount = 0L;
   newBlogPost.subject = postForm.get().subject;
   newBlogPost.content = postForm.get().content;
   newBlogPost.user = getUser();
   newBlogPost.save();
 }
 return ok(Application.buildJsonResponse("success", "Post added successfully"));
}


private static User getUser() {
 return User.findByEmail(session().get("username"));
}

 public static class PostForm {

   @Constraints.Required
   @Constraints.MaxLength(255)
   public String subject;

   @Constraints.Required
   public String content;

 }
}
Add a new entry to the routes file to be able to handle newly added methods in routing:
POST        /app/post                   controllers.Post.addPost
At this point, you should be able to add new posts.

Displaying Posts

Adding posts have little value, if we can’t display them. What we want to do is list all posts on the main page. We begin by adding a new method in our application controller:
// Application.java

public static Result getPosts() {
 return ok(Json.toJson(BlogPost.find.findList()));
}
And registering it in our routes file:
GET         /app/posts                  controllers.Application.getPosts
Next, in our AngularJS application we modify our main controller:
// main.js

angular.module('clientApp')
   .controller('MainCtrl', function ($scope, $http) {
     $scope.getPosts = function() {
       $http.get('app/posts')
           .success(function(data) {
             $scope.posts = data;
           });
     };

     $scope.getPosts();

   });
Finally, remove everything from “main.html” and add this:
<div class="panel panel-default" ng-repeat="post in posts">
 <div class="panel-body">
   <h4>{{ post.subject }}</h4>
   <p>
     {{ post.content }}
   </p>
 </div>

 <div class="panel-footer">Post by: {{ post.user.email }} | <a
     ng-href="/#/viewpost/{{ post.id }}">Comments
   <span class="badge">{{ post.commentCount }}</span></a></div>
</div>
Now if you load your application home page you should be seeing something similar to this:
We should also probably have a separate view for individual posts.
yo angular:controller viewpost
yo angular:view viewpost
// viewpost.js

angular.module('clientApp')
   .controller('ViewpostCtrl', function ($scope, $http, alertService, userService, $location) {

     $scope.user = userService;
     $scope.params = $routeParams;
    $scope.postId = $scope.params.postId;

     $scope.viewPost = function() {
       $http.get('/app/post/' + $scope.postId)
           .error(function(data) {
             alertService.add('danger', data.error.message);
           })
           .success(function(data) {
             $scope.post = data;
           });
     };

     $scope.viewPost();
   });
<!-- viewpost.html -->

 <div class="panel panel-default" ng-show="post">
 <div class="panel-body">
   <h4>{{ post.subject }}</h4>
   <p>
     {{ post.content }}
   </p>
 </div>

 <div class="panel-footer">Post by: {{ post.user.email }} | Comments
   <span class="badge">{{ post.commentCount }}</span></a></div>
</div>
And the AngularJS route:
app.js:
.when('/viewpost/:postId', {
templateUrl: 'views/viewpost.html',
controller: 'ViewpostCtrl'
})
Like before, we add a new method to our application controller:
// Application.java

public static Result getPost(Long id) {
 BlogPost blogPost = BlogPost.findBlogPostById(id);
 if(blogPost == null) {
   return notFound(buildJsonResponse("error", "Post not found"));
 }
 return ok(Json.toJson(blogPost));
}
… And a new route:
GET         /app/post/:id               controllers.Application.getPost(id: Long)
Now if you navigate to http://localhost:9000/#/viewpost/1, you will be able to load a view for a particular post. Next, let’s add the ability to see user’s posts in the dashboard:
// dashboard.js

angular.module('clientApp')
   .controller('DashboardCtrl', function ($scope, $log, $http, alertService, $location) {

     $scope.loadPosts = function() {
       $http.get('/app/userposts')
           .error(function(data, status) {
             if(status === 401) {
               $location.path('/login');
             } else {
               alertService.add('danger', data.error.message);
             }
           })
           .success(function(data) {
             $scope.posts = data;
           });
     };

     $scope.loadPosts();
   });
<!-- dashboard.html -->

<h4>My Posts</h4>
<div ng-hide="posts.length">No posts yet. <a ng-href="/#/addpost">Add a post</a></div>
<div class="panel panel-default" ng-repeat="post in posts">
 <div class="panel-body">
   <a ng-href="/#/viewpost/{{ post.id }}">{{ post.subject }}</a> | Comments
   <span class="badge">{{ post.commentCount }}</span>
 </div>
</div>
Also add a new method to Post controller, followed by a route corresponding to this method:
// Post.java

public static Result getUserPosts() {
 User user = getUser();
 if(user == null) {
   return badRequest(Application.buildJsonResponse("error", "No such user"));
 }
 return ok(Json.toJson(BlogPost.findBlogPostsByUser(user)));
}
GET         /app/userposts              controllers.Post.getUserPosts
Now when you create posts, they will be listed on the dashboard:

Commenting Functionality

To implement commenting functionality, we will begin by adding a new method in Post controller:
// Post.java

public static Result addComment() {
 Form<CommentForm> commentForm = Form.form(CommentForm.class).bindFromRequest();

 if (commentForm.hasErrors()) {
   return badRequest(commentForm.errorsAsJson());
 } else {
   PostComment newComment = new PostComment();
   BlogPost blogPost = BlogPost.findBlogPostById(commentForm.get().postId);
   blogPost.commentCount++;
   blogPost.save();
   newComment.blogPost = blogPost;
   newComment.user = getUser();
   newComment.content = commentForm.get().comment;
   newComment.save();
   return ok(Application.buildJsonResponse("success", "Comment added successfully"));
 }
}


public static class CommentForm {

 @Constraints.Required
 public Long postId;

 @Constraints.Required
 public String comment;

}
And as always, we need to register a new route for this method:
POST        /app/comment                controllers.Post.addComment
In our AngularJS application, we add the following to “viewpost.js”:
$scope.addComment = function() {
 var payload = {
   postId: $scope.postId,
   comment: $scope.comment
 };

 $http.post('/app/comment', payload)
     .error(function(data, status) {
       if(status === 400) {
         angular.forEach(data, function(value, key) {
           if(key === 'comment') {
             alertService.add('danger', key + ' : ' + value);
           } else {
             alertService.add('danger', value.message);
           }
         });
       } else if(status === 401) {
         $location.path('/login');
       } else if(status === 500) {
         alertService.add('danger', 'Internal server error!');
       } else {
         alertService.add('danger', data);
       }
     })
     .success(function(data) {
       alertService.add('success', data.success.message);
       $scope.comment = '';
       $scope.viewPost();
     });
};
And finally add the following lines to “viewpost.html”:
<div class="well" ng-repeat="comment in post.comments">
 <span class="label label-default">By: {{ comment.user.email }}</span>
 <br/>
 {{ comment.content }}
</div>

<div ng-hide="user.username || !post"><h4><a ng-href="/#/login">Login</a> to comment</h4></div>
<form name="addCommentForm" ng-submit="addComment()" novalidate ng-show="user.username">
 <div><h4>Add comment</h4></div>
 <div>
   <label for="comment">Comment</label>
   <textarea name="comment" class="form-control" id="comment" placeholder="Comment"
             ng-model="comment"></textarea>
 </div>

 <button type="submit" class="btn btn-primary">Add comment</button>
</form>
Now if you open any post, you will be able to add and view comments.

What’s Next?

In this tutorial, we have built an AngularJS blog with a Play application serving as a REST API back-end. Although the application lacks robust data validation (especially on the client side) and security, these topics were out of the scope of this tutorial. It was aiming to demonstrate one of the many possible ways of building an application of this kind. For convenience, the source code of this application has been uploaded to a GitHub repository.
If you find this combination of AngularJS and Play in web application development interesting, I highly recommend you review the following topics further: