AngularJS structure and directives

Today I am going to tell you how to build a well worked Angular JS structure, as well as to be able to maintain your app’s elements correctly. It’s a basic and most important thing to learn and remember before you start building your own website or app because in the early phases of a project the structure doesn’t matter too much, and many people tend to ignore it, but in the long term it will affect code maintainability. It also helps you to develop it quicker and solve bugs without any additional troubles.

I must admit that I was one of them who  had made this mistake and ignore AngularJS correct structure. The thing is that I had not known how to build Angular JS app correctly before I started coding CommonsNet, and I wanted to start and provide a real outcome as quickly as possible. But unfortunately my mistake has stoped me later. I have realised it this week while implementing a quite simple feature – adding HTML elements dynamically. It turned out that I had a trouble while adding them. I had’t known that it’s better not to manipulate DOM elements in Controllers, but instead do it in directives.

Let me to explain it step by step from lessons I’ve learned while refactoring CommonsNet code structure. Please note that I’m just sharing my experience in building rather a small project and I’m covering only a small part of that subject, so some of these tips may be first – useless if you want to build an extended one, and then – not enough if you want to learn more. I recommend you to find further resources.

AngularJS Structure

First of all please see at AngularJS structure provided below. It’s a very basic structure, but it’ is important to have in mind that you should follow that pattern while developing your own app. If you want to have an order in your files you should seperate them by directories and create different ones like: controllers, directives, services, js and views. This structure makes it very easy for the reader to visualize and conceptualize the concepts you are covering.

AngularJS structure.png

My CommonsNet structure differs a bit because I have one main js directory, and all subdirectories like directives, controllers and services  inside it. I think it’s also an acceptable solution. Imagine that I hadn’t had any directives or services directives’ files before last Wednesday…

Then,  it’s also recommended to put index.html at the root of front-end structure. The index.html file will primarily handle loading in all the libraries and Angular elements.

Next, controllers are main part of AngularJS apps. It always happens that developers when starting out tend to put too much logic in the controllers. It’s a bug. Controllers should never do DOM manipulation or hold DOM selectors, that’s where we use directives and ng-model. Likewise business logic should live in services, not controllers.

Data should also be stored in services, except where it is being bound to the $scope. Services are singletons that persist throughout the lifetime of the application, while controllers are transient between application states. So, if the controller is a coordinator between the view and the model, then the amount of the logic it has should be minimal.

Directives

Take a look at a very basic AngularJS directive. Let’s name this file appInfo.js as well as create an .html file appInfo.html as in example below.

Learn AngularJS 1.X   Codecademy.png

In this example we create a new directive called appInfo. It returns an object with three options – restrict, scope and templateURL

  1. restrict specifies how the directive will be used in the view. The 'E' means it will be used as a new HTML element.
  2. scope specifies that we will pass information into this directive through an attribute named info. The = tells the directive to look for an attribute named info in the <app-info> element, like this: The data in info becomes available to use in the template given by templateURL.
  3. templateUrl specifies the HTML to use in order to display the data in scope.info. Here we use the HTML in js/directives/appInfo.html.

Then we need to build a structure to directive in our appInfo.html

<h2 class="title">{{ info.title }}</h2> 
<p class="developer">{{ info.developer }}</p> 
<p class="price">{{ info.price | currency }}</p>

Of course <h2> and <p> are just examples. You can use here what you only want. The title and developer are controller $scope.elements. Let’s take a look at controller’s content.

$scope.apps = [ 
 { 
 title: 'MOVE', 
 developer: 'MOVE, Inc.', 
 price: 0.99 
 }, 
 { 
 title: 'Shutterbugg', 
 developer: 'Chico Dusty', 
 price: 2.99 
 }, 
]

In index.html we use only  ng-repeat to loop through app element in $scope.apps, and then app-info info=”app”

<div ng-repeat="app in apps">
     <app-info info="app"></app-info>
</div>

That’s it. It’s quite a simple example, but it helps me to refactor my code in CommonsNet project and avoid a long, boring, repetitive work while adding new elements to website. It also helps me to implement a feature I have mentioned above. I’am going to tell more about it in next blog post. Stay tuned!

Resources:

https://scotch.io/tutorials/angularjs-best-practices-directory-structure

https://www.codecademy.com/learn/learn-angularjs.

https://commonsnetblog.wordpress.com/

 

sTeam REST API Unit Testing

(ˢᵒᶜⁱᵉᵗʸserver) aims to be a platform for developing collaborative applications.
sTeam server project repository: sTeam.
sTeam-REST API repository: sTeam-REST

Unit Testing the sTeam REST API

The unit testing of the sTeam REST API is done using the karma and the jasmine test runner. The karma and the jasmine test runner are set up in the project repository.

The karma test runner : The main goal for Karma is to bring a productive testing environment to developers. The environment being one where they don’t have to set up loads of configurations, but rather a place where developers can just write the code and get instant feedback from their tests. Because getting quick feedback is what makes you productive and creative.

The jasmine test runner: Jasmine is a behavior-driven development framework for testing JavaScript code. It does not depend on any other JavaScript frameworks. It does not require a DOM. And it has a clean, obvious syntax so that you can easily write tests.

The karma and jasmine test runner were configured for the project and basic tests were ran. The angular js and angular mocks version in the local development repository was different. This had resulted into a new error been incorporated into the project repo. The ‘angular.element.cleanData is not a function’ error is thrown in the local development repository. This error happens when the local version of the angular.js and angular-mocks.js doesn’t match. The testing framework would test you if the versions f the two libraries is not the same.

The jasmine test runner can be accessed from the browser. The karma tests can be performed from the command line.

To access the jasmine test runner from the web browser, go to the url

http://localhost:7000/test/unit/runner.html

To run the karma test suite, run the following command

$ karma start

The unit tests of the sTeam REST service were done using jasmine. The unit tests were written in coffee script. The preprocessor to compile the files from coffee script to javascript is defined in the karma configuration file.

Jasmine Test RunnerJasmineRunner
Jasmine Test Failure

JasmineRunnerFailure

First a dummy pass case and a fail case is tested to check there are no errors in the test suite during the test execution.

The localstoragemodule.js which is used in the steam service is injected in the test module. Then the steam service version is tested.

describe 'Check version of sTeam-service', -> 
 		it 'should return current version', inject (version) -> 
 			expect(version).toEqual('0.1') 

steam service should be injected in a global variable as the same service functions shall be tested while performing the remaining tests.
Then the steam service is injected and checked whether it exists or not.

beforeEach inject (_steam_) -> 
 		steam= _steam_ 
 	describe 'Check sTeam service injection', ->  
 		it 'steam service should exist', -> 
 			expect(steam).toBeDefined() 

The sTeam service has both private and public functions. The private functions cannot be accessed from outside. The private functions defined in the sTeam service arehandle_request and headers.

describe 'Check sTeam service functions are defined.', ->  
 		describe ' Check the sTeam REST API private functions.', -> 
 			it 'steam service handle request function should exist', -> 
 				expect(steam.handle_request).toBeDefined() 
 			it 'steam service headers function should exist', -> 
 				expect(steam.headers).toBeDefined() 

The public functions of the sTeam service are then tested.

describe 'Check sTeam service functions are defined.', ->  
 		describe ' Check the sTeam REST API public functions.', -> 
 			it 'steam service login function should exist', -> 
 				expect(steam.login).toBeDefined() 
 			it 'steam service loginp function should exist', -> 
 				expect(steam.loginp).toBeDefined() 
 			it 'steam service logout function should exist', -> 
 				expect(steam.logout).toBeDefined() 
 			it 'steam service user function should exist', -> 
 				expect(steam.user).toBeDefined() 
 			it 'steam service get function should exist', -> 
 				expect(steam.get).toBeDefined() 
 			it 'steam service put function should exist', -> 
 				expect(steam.put).toBeDefined() 
 			it 'steam service post function should exist', -> 
 				expect(steam.post).toBeDefined() 
 			it 'steam service delete function should exist', -> 
 				expect(steam.delete).toBeDefined() 

The test suite written by Siddhant for the sTeam server was tested. The merging of the code from different branches which includes the work done during the course of GSoC 2016 will be merged subsequently.

Karma test runner

KarmaTestCase

Feel free to explore the repository. Suggestions for improvements are welcomed.

Checkout the FOSSASIA Idea’s page for more information on projects supported by FOSSASIA.

 

Angular API testing with frisby and jasmine-node

week9gsoc1

sTeam-web-UI is an application written in angular. So the application relies on sTeam's existing REST api which is written in pike. Since there are a lot of API calls and actions involved ensuring that the application is making proper API calls and getting proper responses is crucial. In order to go ahead with the API testing there are two important things to be know about first.

  • frisby
  • jasmine

What is frisby ?

“Frisby is a REST API testing framework built on node.js and Jasmine that makes testing API endpoints easy, fast, and fun. Read below for a quick overview, or check out the API documentation.”

What is Jasmine ?

“Jasmine is a Behavior Driven Development testing framework for JavaScript. It does not rely on browsers, DOM, or any JavaScript framework. Thus it’s suited for websites, Node.js projects, or anywhere that JavaScript can run.”

The api methods present in frisby can be categorized into :

  • Expectations
  • Helpers
  • Headers
  • Inspectors

So let me show couple of tests that are written with the help of frisby for the sTeam's web interface.

Checking the Home directory of the user :


frisby.create('Request `/home` returns proper JSON')
  .get(config.baseurl + 'rest.pike?request=/home')
  .expectStatus(200)
  .expectJSON({
    'request': '/home',
    'request-method': 'GET',
    'me': objUnit.testMeObj,
    'inventory': function (val) {
      val.forEach(function (e) {
        objUnit.testInventoryObj(e)
      })
    }
  })
.toss()

Checking the container of the user :


frisby.create('Request `/home/:user` returns proper JSON')
  .get(config.baseurl + 'rest.pike?request=/home/akhilhector/container')
  .expectStatus(200)
  .expectJSON({
    'request': '/akhilhector',
    'request-method': 'GET',
    'me': objUnit.testMeObj,
    'inventory': function (val) {
      val.forEach(function (e) {
        objUnit.testInventoryObj(e)
      })
    }
  })
.toss()

Accessing the file in the user’s workarea :


frisby.create('Request `/home/:user/:container/:filename` returns proper JSON')
  .get(config.baseurl + 'rest.pike?request=//home/akhilhector/playground-hector/icon1.png')
  .expectStatus(200)
  .expectJSON({
    'request': '/akhilhector/playground-hector/icon1.png',
    'request-method': 'GET',
    'me': objUnit.testMeObj,
    'inventory': function (val) {
      val.forEach(function (e) {
        objUnit.testInventoryObj(e)
      })
    }
  })
.toss()

Observing the above three modules, each of them are different from one another. We have to understand that depending on the API the request payload must be sent. So for suppose the API needs authentication headers to be sent then we need to use the proper helper methods of frisby in order to send the same.
The .get() can be substituted with put, post, delete. Basically all the frisby tests start with frisby.create with a description of the test followed by one of get, post, put, delete, or head, and ending with toss to generate the resulting response.
Apart from the request payload there is an interesting thing with the helper method expectJSON, it is used for testing the given path or full JSON response of the specified length. In order to use expectJSON we must pass the path as the primary argument and the JSON as the second argument.
The expectStatus helper method is pretty straightforward. It helps us in determining the HTTP Status code equivalent of the request so made.

NOTE While writing the tests it is better to put all the config in one place and use that config variable for all the operations.

Thats it folks,
Happy Hacking !!

sTeam API Endpoint Testing

(ˢᵒᶜⁱᵉᵗʸserver) aims to be a platform for developing collaborative applications.
sTeam server project repository: sTeam.
sTeam-REST API repository: sTeam-REST

sTeam API Endpoint Testing using Frisby

sTeam API endpoint testing is done using Frisby.  Frisby is a REST API testing framework built on node.js and Jasmine that makes testing API endpoints very easy, speedy and joyous.

Issue. Github Issue Github PR
sTeam-REST Frisby Test for login Issue-38 PR-40
sTeam-REST Frisby Tests Issue-41 PR-42

Write Tests

Frisby tests start with frisby.create with a description of the test followed by one of get, post, put, delete, or head, and ending with toss to generate the resulting jasmine spec test. Frisby has many built-in test helpers like expectStatus to easily test HTTP status codes, expectJSON to test expected JSON keys/values, and expectJSONTypes to test JSON value types, among many others.

// Registration Tests
frisby.create('Testing Registration API calls')
.post('http://steam.realss.com/scripts/rest.pike?request=register', {
email: "[email protected]",
fullname: "Ajinkya Wavare",
group: "realss",
password: "ajinkya",
userid: "aj007"
}, {json: true})
.expectStatus(200)
.expectJSON({
"request-method": "POST",
"request": "register",
"me": restTest.testMe,
"__version": testRegistrationVersion,
"__date": testRegistrationDate
})
.toss();
The testMe, testRegistrationVersion and testRegistrationDate are the functions written in the rest_spec.js.

The frisby API endpoint tests have been written for testing the user login, accessing the user home directory, user workarea, user container, user document, user created image,  groups and subgroups.

The REST API url’s used for testing are described below. A payload consists of the user id and password.

Check if the user can login.

http://steam.realss.com/scripts/rest.pike?request=aj007

Test whether a user workarea exists or not. Here aj workarea has been created by the user.

http://steam.realss.com/scripts/rest.pike?request=aj007/aj

Test whether a user created container exists or not.

http://steam.realss.com/scripts/rest.pike?request=aj007/container

Test whether a user created document exists or not.

http://steam.realss.com/scripts/rest.pike?request=aj007/abc.pike

Test whether a user created image(object of any mime-type) inside a container exists or not.

http://steam.realss.com/scripts/rest.pike?request=aj007/container/Image.jpeg

Test whether a user created document exists or not. The group name and the subgroups can be queried.
eg. GroupName: groups, Subgroup: test.
The subgroup should be appended using “.” to the groupname.

http://steam.realss.com/scripts/rest.pike?request=groups.test

Here “groups” is a Groupname and “gsoc” is a subgroup of it.

http://ngtg.techgrind.asia/scripts/rest.pike?request=groups.gsoc

FrisbyTests

FrisbyTestCount

Unit Testing the sTeam REST API

The unit testing of the sTeam REST API is done using the karma and the jasmine test runner. The karma and the jasmine test runner are set up in the project repository.

The karma test runner : The main goal for Karma is to bring a productive testing environment to developers. The environment being one where they don’t have to set up loads of configurations, but rather a place where developers can just write the code and get instant feedback from their tests. Because getting quick feedback is what makes you productive and creative.

The jasmine test runner: Jasmine is a behavior-driven development framework for testing JavaScript code. It does not depend on any other JavaScript frameworks. It does not require a DOM. And it has a clean, obvious syntax so that you can easily write tests.

The karma and jasmine test runner were configured for the project and basic tests were ran. The angular js and angular mocks version in the local development repository was different. This had resulted into a new error been incorporated into the project repo.

Angular Unit-Testing: TypeError ‘angular.element.cleanData is not a function’

When angular and angular-mocks are not of the same version, these error occurs while running the tests. If the versions of the two javascript libraries don’t match your tests will be testing to you.

The jasmine test runner can be accessed from the browser. The karma tests can be performed from the command line. These shall be enhanced further during the course of work.

Feel free to explore the repository. Suggestions for improvements are welcomed.

Checkout the FOSSASIA Idea’s page for more information on projects supported by FOSSASIA.

Developing Image Viewer in Angular JS

week8gsoc0

In the previous article i have addressed about developing audio and video players for sTeam. To know more about developing audio and video players, click here. This article is an extension to the previous one, as to how one could develop image viewer in angular.
Since sTeam is a collaboration platform there was the necessity of having an image viewer. So in angular bootstrapLightbox is very useful in building image viewers, galleries, sliders etc.

Implementation Strategy :
There are basically two things involved in developing this;

The Controller

angular.module('steam', [ 'bootstrapLightbox', 'ui.bootstrap' ])
  .controller('steamImageViewer', ['$scope', 'Lightbox', function($scope, Lightbox) {
    $scope.images = [
    {
      'url': 'https://societyserver.org/home/akhilhector/playground%20-%20hector/icon1.png',
      'title': 'icon1.png'
    },
    {
      'url': 'https://societyserver.org/home/akhilhector/playground%20-%20hector/icon3.jpg',
      'title': 'icon3.jpg'
    },
    {
      'url': 'https://societyserver.org/home/akhilhector/playground%20-%20hector/icon4.png',
      'title': 'icon4.png'
    },
    {
      'url': 'https://societyserver.org/home/akhilhector/playground%20-%20hector/icon4.jpg',
      'title': 'icon4.jpg'
    }
    ];
    $scope.imageViewer = function (index) {
      Lightbox.openModal($scope.images, index);
    };
  }]);

Observe the controller over here, we pass an array of images or a single image to an array object and then we use the same for our DOM. Options like URL, Title, and Thumbnail can be passed in the same object. In the same controller we need to write another function that uses the LightBox service in order to open a modal and serve the image which was passed as an URL. So the modal displays whatever source is being passed as an argument. Also if we are using a REST api for retrieving the images then we can have a we can have similar array object that stores all the information recieved from the api response. In order to better this, there can be a mime-handler written so that if an unknown/unsupported mime type is being requested for, then an error can be popped.

The HTML

<div class="row" ng-controller="steamImageViewer">
    <div class="col-md-12" ng-repeat="image in images">
        <div class="roomItem">
            <div class="roomItemIcon roomItemBlue"><i class="fa fa-image"></i>
            </div>
            <div class="itemText"> {{image.title}} <a href="#" ng-click="imageViewer($index)">view</a>
            </div>
        </div>
    </div>
</div>

The above DOM seems pretty straight forward, we use the help of the function which we previously wrote in the controller in order to get the data. So as soon as we click the Lightbox modal fires and displays the image. It is to be observed that this implementation goes with consideration that there are an array of images that are ought to be retrieved, but the same logic wouldn’t be fruitful for displaying a single image. In order to acheive that we can pass the image object to the $scope and use the same for displaying the image. And minor changes in the HTML will help displaying a single image instead of an array of images.

So here is how it looks :

week8gsoc3

week8gsoc2

week8gsoc1

Thats it folks,
Happy Hacking !!

Generating Documentation and Modifying the sTeam-REST API

(ˢᵒᶜⁱᵉᵗʸserver) aims to be a platform for developing collaborative applications.
sTeam server project repository: sTeam.
sTeam-REST API repository: sTeam-REST

Documentation

Documentation is an important part of software engineering. Types of documentation include:

  1. Requirements – Statements that identify attributes, capabilities, characteristics, or qualities of a system. This is the foundation for what will be or has been implemented.
  2. Architecture/Design – Overview of software. Includes relations to an environment and construction principles to be used in design of software components.
  3. Technical – Documentation of code, algorithms, interfaces, and APIs.
  4. End user – Manuals for the end-user, system administrators and support staff.
  5. Marketing – How to market the product and analysis of the market demand.

Doxygen

Doxygen is the de facto standard tool for generating documentation from annotated C++ sources, but it also supports other popular programming languages such as C, Objective-C, C#, PHP, Java, Python, IDL (Corba, Microsoft, and UNO/OpenOffice flavors), Fortran, VHDL, Tcl, and to some extent D.
The Doxygen treats files of other languages as C/C++ and creates documentation for it accordingly.
sTeam documentation was tried to be created with the doxygen. But empty documentation was created due to the lack of the doxygen annotations used in the project.
 Doxygen doc generation.
DoxyGenTerminal
Doxygen Docs
DoxyDoc
The next way to create documentation was to make use of the autodoc utility provided by the Pike. The utility to generate docs was provided in the later versions of the Pike(>=8.0.155).
The autodoc files are generated and  later these are converted into  html pages. The commands used for generating the autodoc include:-
pike -x extract_autodoc /source
pike -x autodoc_to_html /src /opfile
The autodoc_to_html utility converts a single autodoc file to an html page. As a result a shell script was written to convert all the generated autodoc files to the html file.
docGenerator.sh
#!/bin/bash  

shopt -s globstar  
for filename in ./**/*.pike.xml; do  
    outputFile=doc/${filename#./}  
    outputFile=${outputFile%.xml}."html"  
    if [ -d $(dirname "./"$outputFile) ]; then  
      touch "./"$outputFile  
    else  
      mkdir -p $(dirname "./"$outputFile) && touch "./"$outputFile  
    fi  
    pike -x autodoc_to_html $filename "./"$outputFile  
done  

Autodoc Documentation
AutoDocThe documentation generated by this was less informative and lacked the referrals to other classes and headers. The societyserver project was developed long back but the autodoc utility was introduced in the later versions of pike. As a result the source files lacked the autodoc tags which are required to generate a well informative documentation with bindings to other files.

Restructuring the sTeam-REST API

The sTeam-REST API project made use of the angular-seed to initiate the development during the early phases. However these files still existed in the project. This had lead to a pandemonium and created difficulty in understanding the project. The files had to be removed and the app was in dire need of a restructuring. The following issues have been reported and resolved.

Issue. Github Issue Github PR
sTeam-REST Issues Issues PR

The new UI can be seen below.

Home

Home

Register

Register

About

About

Testing the REST API

The functionality to run the tests using the npm test command was added to the project. Now the user can run the tests using these commands instead of the traditional approach of running the tests using jasmine-node and specifying the test directory. The domain name of the urls to which the request was sent was changed. The e2e tests and frisby tests were conducted successfully.

e2e Tests.

e2eTests

Frisby Tests

NPM tests

The next step would be to do add more tests for the REST API.

Feel free to explore the repository. Suggestions for improvements are welcomed.

Checkout the FOSSASIA Idea’s page for more information on projects supported by FOSSASIA.

sTeam REST API

(ˢᵒᶜⁱᵉᵗʸserver) aims to be a platform for developing collaborative applications.
sTeam server project repository: sTeam.
sTeam-REST API repository: sTeam-REST

REST Services

REST is the software architectural style of the World Wide Web. REST (Representational State Transfer) was introduced by Roy Fielding in his doctoral dissertation in 2000. Its purpose is to induce performance, scalability, simplicity, modifiability, visibility, portability, and reliability.It has client/server relationship with a uniform interface and is stateless. REST is most commonly associated with HTTP but it is not strictly related to it.

REST Principles

  • Resources : Each and every component is a resource.A resource is accessed by a common interface using HTTP standard methods.
  • Messages use HTTP methods like GET, POST, PUT, and DELETE.
  • Resource identification through URI: Resources are identified using URI. Resources are represented using JSON or XML.
  • Stateless interactions take place between the server and the client. No context is saved for the requests at the server.The client maintains the state of the session.

HTTP methods

The CRUD(create, retrieve, update and delete ) operations are performed using the HTTP methods.

GET

It is used to retrieve information. GET requests executed any number of times with the same parameters, the results would not change. This makes it idempotent. Partial or conditional requests can be sent. It is a read only type of operation.

Retrieve a list of users:

GET /api.example.com/UserService/users

POST

POST is usually used to create a new entity. It can also be used to update an existing entity. The request will have to do something with the entity provided in the URI.

Create a new user with an ID 2:

POST /api.example.com/UserService/users/2

PUT

PUT request is always idempotent. Executing the same request any number of times will not change the output. PUT can be used to create or update an existing entity.

Modify the user with an ID of 1:

PUT /api.example.com/UserService/users/1

PATCH

It is idempotent. PATCH requests only updates the specified fields of an entity.

Modify a user with an id of 1:

PATCH /api.example.com/UserService/users/1

DELETE

It can be asynchronous or a long-running request. It removes the resource. It can be removed immediately or at a later instance of time.

Delete a user with an ID of 1:

DELETE /api.example.com/UserService/users/1

 sTeam-REST API

Installing and activating the REST API

The REST API is developed as an application inside the sTeam server. This simplifies development quite a lot, as we don’t need to restart the server for every change. Instead just the API code gets updated and reloaded. It may eventually be integrated into the core, however the longterm plan is actually to move functionality out of the core, to make development easier.

To get the current version of the API clone the steam-rest repo into your home or to any place where you keep your development repos. Then change to the tools directory of your installation and run import-from-git.

git clone https://github.com/societyserver/steam-rest
cd steam-rest
git checkout origin/rest.pike
export steamrest=`pwd`
cd /usr/local/lib/steam/tools
./import-from-git.pike -u root $steamrest /

Note: The new import-from-git.pike script supports importing documents of all mime types.

It is important that the first import is done as root because the API code needs to run with root privileges and it will only do that if the object that holds the source is created as root.

Once the api code is loaded there are just a few tweaks needed to make it work.

We need to fix the mime-type, as the import script is not doing that yet.

OBJ("/sources/rest.pike")->set_attribute("DOC_MIME_TYPE", "source/pike");

Changing the mime type will change the class of the rest api script from Document to DocLpc.

> OBJ("/sources/rest.pike");                                               
(1) Result: 127.0.0.1:1900/rest.pike(#840,/classes/Document,17,source/pike)
> OBJ("/sources/rest.pike");                                               
(2) Result: 127.0.0.1:1900/rest.pike+(#840,/classes/DocLpc,529,source/pike,0 Instances, ({  }))

This takes a moment, check the type a few times until it’s done. Then instantiate an object from the source, give it a proper name, and move it to the /scripts/ container”

object rest = OBJ("/sources/rest.pike")->provide_instance();
rest->set_attribute("OBJ_NAME", "rest.pike");
rest->move(OBJ("/scripts/"));

Instantiating the object needs to be done as sTeam-root, in order for it to have permissions to run on behalf of other users.

Once this is done you are ready to start using the API.

sTeam-REST API tests

The project contains a set of examples and tests for the RESTful API for the sTeam server.

The code is written in coffee script and needs node.js only for coffeescript translation. Deployment can be done as static javascript files, and does not need any kind of dynamic server for the front-end. The back-end is a RESTful API written for the sTeam server as used by steam.realss.com

Development instructions

step 1: install node.js

http://nodejs.org/download/

step 2: clone the repository

git clone https://github.com/societyserver/steam-rest

step 3: install node packages:

npm install

This installs all dependencies (including coffee) for our project into the project’s node_modules directory based on the ‘package.json’ file

step 4: start the server

node_modules/.bin/coffee scripts/server.coffee

but for convenience we can install coffee in the global node environment:

npm install -g coffee-script

so we can just say

coffee scripts/server.coffee

if the server is working you’ll see:

Listening on port 7000

Testing

FrisbyJS is used to test the API. It is run through Jasmine and is based on nodejs.

Once you have nodejs installed, run the following statement to install Frisby and Jasmine:

npm install -g jasmine-node frisby

Then execute the test by:

cd project/directory
jasmine-node test/

The karma testing framework is also used for testing the sTeam REST API.

There were some inherent issues with the test framework which were addressed.

Issue. Github Issue Github PR
Update Readme.md Update Readme PR-2
Add javascript dependencies Issue-4 PR-6
Add node dependencies Issue-5 PR-7
Add angular-mocks.js script for testing the REST services. Issue-8 PR-9

The project dependencies were not met and this resulted into the error when the project was run on the localhost. The angular-ui-router, angular-bootstrap and bootstrap js frameworks were not installed in the node modules of the project. As a result the bower.json script was modified to include these dependencies.

bower.json

{
  "name": "bower",
  "version": "0.1",
  "private": true,
  "ignore": [
    "**/.*",
    "node_modules",
    "bower_components",
    "test",
    "tests"
  ],
  "dependencies": {
    "angular": "",
    "angular-route": "~1.4.8",
    "angular-ui-router": "",
    "angular-bootstrap": "",
    "bootstrap": ""
  }
}

The node dependencies of karma, frisby and jasmine-node were included in the package.json. These would be installed when the npm install is executed.

package.json

{
"name": "TechGrind",
"version": "0.1.1",
"private": true,
"dependencies": {
"express": "",
"coffee-script": "",
"morgan": "",
"compression": "",
"method-override": "",
"body-parser": "",
"serve-static": "",
"errorhandler": "",
"bower": "",
"jasmine-node": "",
"frisby": "",
"karma": ""
},
"production_dirs": {
"coffee_src": "src/",
"src": "app/",
"dest": "app_production/"
},
"devDependencies": {
},
"scripts": {
"postinstall": "bower install"
}
}

Feel free to explore the repository. Suggestions for improvements are welcomed.

Checkout the FOSSASIA Idea’s page for more information on projects supported by FOSSASIA.

The beauty of Directives, Transclusion in Angular.JS

week3gsoc1

To be honest in Angular directives are nothing but DOM elements simply put on steroids. Now if you add transclusion to it literally the possibilty of exploring the playground is boundless .With that said before diving into what directives are and how cool are they, let us basically understand what makes directives in angular so powerful.

Some of the well known directives which are used regularly are :

  • ng-src
  • ng-show
  • ng-hide
  • ng-model
  • ng-repeat

Custom Directives and the benifit of creating reusable components

We often tend to waste a lot of time and energy in writing code which is already/previously written and components which are already built. But what if you could write them only once and reuse them as many times as possible ?
ANS : “Directives”
You can create truly reusable components with directives, and the approach to build custom components is definitely neater and more intuitive.
Where do Custom Directives get implemented ?

  • elements
  • attributes
  • classes

Scope of Directives

After we initialize a directive we can observe that it gets a parent scope by default. In the best interests of the application you write you won’t really want that to happen. So in order to freely modify the properties of the directive we expose the parent’s controller scope to the directives.In some cases your directive may want to add several properties and functions to the scope that are for internal use only.

Example : If you have a directive that deals with comments(just like my sTeam web interface), you may want to set some internal variable to show or hide some of its specific sections. If we set these models to the parent’s scope we would pollute it.

Without polluting, is there any option ?

Absolutely there are two options,

  • Use a child scope
  • Use an isolated scope

If we use a child scope then the child scope prototypically inherits the parent’s scope. If we use an isolated scope then its all on its own, by not inheriting its parent’s scope

Transclusion

Transclusion is a feature that enables us to wrap a directive around arbitrary content. We can extract and compile it against the correct scope later, and eventually place it at the specified position in the directive template. If you set transclude:true in the directive definition, a new transcluded scope will be created which prototypically inherits from the parent scope. If you want your directive with isolated scope to contain an arbitrary piece of content and execute it against the parent scope, transclusion can be used.

Example :

week3gsoc2

See the above snippet, here ng-transclude says where to put the transcluded content. In this case the DOM content Hello {{name}} is extracted and put inside div ng-tran- sclude /div> . The important point to remember is that the expression {{name}} interpolates against the property defined in the parent scope rather than the isolated scope.

Thats it folks,
Happy Hacking !!

Promises, REST API’s & Angular JS

week2gsoc1

Before breaking it down, to all those who don’t know what REST API’s are :

“REST is acronym for REpresentational State Transfer. It is architectural style for distributed hypermedia systems ans was first presented by Roy Fielding in 2000 in his famous dissertation.”

Source : “restfulapi.net”

So what is a Promise ?

Generally promises are representation of a value that which might not be available to us as of now but at some point eventually it will be available. Observe the below image to understand how promises work.

week2gsoc2

So how is this better than callbacks ?

Generally if you are using callbacks in your codebase then at some point of time either for i/o’s or file buffers or something might come in your way and makes you write nested callbacks. Writing nested callbacks is difficult and an alternative to that is promise.

week2gsoc3

REST API’s, promises what are you about to explain ?

Angular has this beautiful service called $q which is helpful for creating promises and using them in your angular applications. Generally many people have concerns over $q but $q is tightly integrated with the scope life cycle. So be it any task it contains all the necessary features needed by most of the heavy duty asynchronous tasks.

Now to start off angular can be really powerfull with the $http Service provided the fact that it has immense potential in allowing us to create heavy duty REST ful API’s, CRUD operation based web applications etc. So let us understand the $http service first before using promises for creating a REST ful API.

$http
|_____ .success()
For a success(), callback is called asynchronously when the request completes and the response arrives from the server
|_____ .error()
For an error(), the error callback is fired

Callbacks which are accpeted by above methods are :

  • data: It is a response obtained from server.
  • status: HTTP status codes 100x, 200x, 300x, 400x, etc which returned from server.
  • config: Object used for generating the request.
  • headers: Headers sent by the server.
  • statusText: HTTP status text of the status code.

Promise Chaining

Chaining is one of the most important aspects of promises. Here the basic idea is that promises can be composed through chaining. This means you can trigger a specified task only after previous promise has been resolved.

Handling errors by designing a promise that always rejects

No API is complete without writing a handler or a middleware that takes care of all the requests which are generally errored. Designing this will be useful if we want to tell a user about the occurrence of an error in terms of a promise rather than a simple value.

week2gsoc4

NOTE : Generally while using $http Service there are somethings which one should have knowledge of, If we happen to send a JS object as POST data in a POST/PUT request, it’s serialized to JSON before getting sent. Similarly, if the server responds with a JSON string it’s parsed into a JavaScript object and passed to the success callback attached to the promise.

Thats it folks,
Happy Hacking !!

Factories, Services and Controllers

week1gsoc1

So before I start the blog post, it is better if you know more about what sTeam web interface is and what are the capabilites of sTeam. Click here.

So what is a Controller ?

It is simply a a constructor function which is instantiated by AngularJS when it encounters ng-controller directive in HTML.

So what is a Factory ?

In Angular Js a factory is an injectable type which helps us in encapsulating repetitive logic.

How are they helpful for sTeam web interface ?

So as my first week of work started of for GSOC, the core concentration has been on primarily working with the controllers of the workarea and integrating them with the respective views. In an attempt i started of with adding a :

commentsCtrl

: Used for adding comments to the web interface

workspaceeditorCtrl

: Used for integrating textAngular to the web interface

Things apart, in a broader aspect here what should be understood is about how things should be implemented using controllers, factories and services. Let me illustrate how it should be properly done in angular js.

To start off

How are controllers really helpful in Angular and how should they be used ?

Generally we should understand that controllers responsible for augmenting the scope which is done by attaching models and functions to it that are subsequently accessed in the view. There are some things which are to be understood while writing controllers. Lets go one by one,

  • A Straight “No” for all the DOM manipulation. This must be achieved only with directives
  • If you are having a situation where you are about to write repeatable code, then don’t do it with controllers, instead encapsulate them in services.
  • If you are trying to expose the whole controller instance then it isn’t a good idea. In fact the scope object exists in order to clear separation of concern between controller and view .

So what about Factories ?

“Services, factories, and providers are all injectable types. We must understand that Factories in angular Js are just another example for an injectable type. It looks almost the same as Service but when it comes to implementation you can decide and determine what to instantiate and return from the factory”

scribes by hector | Akhil Pandey

Let me give you a small example before i wrap up, Have a look at the below image,

week1gsoc2

Observe broadcastItem, prepForBroadcast. If you look keenly essentially what i am doing there is creating an injectable type which enables me to change the message that which has to be printed depending on the broadcast item.

One more key thing about factories is that a factory can also depend on other services or factories. Also there is one more point to grab which is we are returning an object from the factory function, so we absolutely have the freedom to determine what should be the object which is to be returned, going further we can base it on certain parameters as well.

Thats it folks,
Happy Hacking !!