Tag Archives: Sailsjs

Build a To-Do App Using SailsJS and AngularJS


Build a To-Do App Using Sails.js and AngularJS
By Devan Patel

sshot-10644.png
Devan Patel ( @devanp92 )Tutorials angularJS , javascript , node.js , sails.js AngularJS is an increasingly popular MV*/MVVM Javascript front-end framework that seamlessly integrates with the server-side MVC Node.js framework, Sails.js. Although AngularJS is well known and prevalently used, Sails.js is a more up-and-coming framework.
Sails.js is written in Node.js and utilizes Express as a web server. Additionally, Sails.js comes bundled with Waterline ORM simplifying the data layer by you only having to interchange adapters for most SQL or NoSQL databases.

One of my favorite features is the automatically generated REST API. This is very handy and allows you to create simple and well-designed APIs.

Lastly, it is compatible with many popular front-end frameworks, including AngularJS, Backbone, Ember, iOS, Android, and many more. If you’ve been deciding on which Javascript framework you want to learn – Sails.js is simple, secure, and most of all, fun!
Whether you’re a novice or veteran to AngularJS or Sails.js this blog post will illustrate how both frameworks interact with each other by building a to-do application.
To see the full source code of this project, check it out here.

Getting Started

Installing Dependencies

Before jumping into the code, we will need to install npm (which additionally installs Node.js) to utilize the necessary packages for this tutorial. With npm installed, we need to grab the Sails.js dependency by running:

$ npm install -g sails

Now let’s generate a Sails.js application by using the sails CLI, sails new todoApp. Hopefully, your directory structure looks like this:

│ Gruntfile.js
│ README.md
│ app.js
│ package.json
└─── api
└───controllers
└───models
└─── policies
│ sessionAuth.js
│ responses
│ badRequest.js
│ forbidden.js
│ notFound.js
│ ok.js
│ serverError.js
│ services
└─── assets
│ favicon.ico
│ images
│ js
│ robots.txt
│ styles
│ templates
└─── images
└─── js
└─── dependencies
│ sails.io.js
└─── styles
│ importer.less
└─── templates
└─── config
│ blueprints.js
│ bootstrap.js
│ connections.js
│ cors.js
│ csrf.js
│ env
│ globals.js
│ http.js
│ i18n.js
│ local.js
│ locales
│ log.js
│ models.js
│ policies.js
│ routes.js
│ session.js
│ sockets.js
│ views.js
└─── env
│ development.js
│ production.js
└─── locales
│ _README.md
│ de.json
│ en.json
│ es.json
│ fr.json
└─── node_modules
└─── ejs
└─── grunt
└─── grunt-contrib-clean
└─── grunt-contrib-coffee
└─── grunt-contrib-concat
└─── grunt-contrib-copy
└─── grunt-contrib-cssmin
└─── grunt-contrib-jst
└─── grunt-contrib-less
└─── grunt-contrib-uglify
└─── grunt-contrib-watch
└─── grunt-sails-linker
└─── grunt-sync
└─── include-all
└─── rc
└─── sails
└─── sails-disk
└─── tasks
│ README.md
│ pipeline.js
└─── config
│ clean.js
│ coffee.js
│ concat.js
│ copy.js
│ cssmin.js
│ jst.js
│ less.js
│ sails-linker.js
│ sync.js
│ uglify.js
│ watch.js
└─── register
│ build.js
│ buildProd.js
│ compileAssets.js
│ default.js
│ linkAssets.js
│ linkAssetsBuild.js
│ linkAssetsBuildProd.js
│ prod.js
│ syncAssets.js
└─── views
│ 403.ejs
│ 404.ejs
│ 500.ejs
│ homepage.ejs
│ layout.ejs

Great! Now we can start our server with sails lift and see our landing page by visiting http://localhost:1337.
sails-new-app-921x500.png
Additionally, we need to update our package.json and create a bower.json file to configure the project to our needs.

package.json

Let’s update the package.json file to have the following packages. Optionally, you can edit the name, author, and many other properties of this file to fit your needs.

{
"name": "todoApp",
"author": "Scotch",
"description": "Sails/Angular Todo Applcation",
"main": "app.js",
"dependencies": {
"bower": "^1.4.1",
"ejs": "~0.8.4",
"forever": "^0.11.1",
"grunt": "0.4.2",
"grunt-contrib-clean": "~0.5.0",
"grunt-contrib-coffee": "~0.10.1",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-copy": "~0.5.0",
"grunt-contrib-cssmin": "~0.9.0",
"grunt-contrib-jst": "~0.6.0",
"grunt-contrib-less": "0.11.1",
"grunt-contrib-uglify": "~0.4.0",
"grunt-contrib-watch": "~0.5.3",
"grunt-sails-linker": "~0.9.5",
"grunt-sync": "~0.0.4",
"include-all": "~0.1.3",
"q": "^1.4.1",
"rc": "~0.5.0",
"sails": "~0.11.0",
"sails-disk": "~0.10.0"
}
}

To install these dependencies, run npm install. Now, we need to customize our front-end configuration. Under the assets directory, run bower init to generate the bower.json file, update it with the following packages and install them with bower install:

bower.json

{
"name": "todoAngularApp",
"dependencies": {
"angular-bootstrap": "~0.11.0",
"angular-moment": "~0.7.1",
"angular-route": "~1.2.17",
"angular": "1.2.19",
"angular-mocks": "~1.2.21",
"jquery": "~2.1.3",
"bootstrap": "~3.3.5"
}
}

One last thing we need to set up is in the tasks/pipeline.js. Pipeline.js tells our program where our dependencies are and which to load.

pipeline.js

var cssFilesToInject = [
'bower_components/bootswatch/dist/css/bootstrap.css',
'styles/**/*.css'
];
var jsFilesToInject = [
 'js/dependencies/sails.io.js',
 '/bower_components/jquery/dist/jquery.js',
 '/bower_components/angular/angular.js',
 '/bower_components/angular-route/angular-route.js',
 '/bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js',
 '/bower_components/bootstrap/dist/js/boostrap.js',
 'js/dependencies/**/*.js',
 'js/**/*.js'
 ];
var templateFilesToInject = [
'templates/*.html'
];
module.exports.cssFilesToInject = cssFilesToInject.map(function(path) {
return '.tmp/public/' + path;
});
module.exports.jsFilesToInject = jsFilesToInject.map(function(path) {
return '.tmp/public/' + path;
});
module.exports.templateFilesToInject = templateFilesToInject.map(function(path) {
return 'assets/' + path;
});

Now with the configuration set up, we can dive into the coding!

Front-end

Layout.ejs

Typically, we need to add a ng-app tag in our HTML, but this needs to be in our views/layout.ejs file. The layout.ejs is where our script and stylesheet tags are and the templating structure. Let’s modify the HTML tag to look like this: .

app.js

Now this is where the actual AngularJS programming comes in. Create assets/js/app.js. The app.js is going to be our primary controller as well as instantiate our angular module. Also, we need to include a method for retrieving all the todos (on page load), adding and remove a todo.

'use strict';
var todoApp = angular.module('todoApp', ['ngRoute', 'ui.bootstrap']);
todoApp.config(['$routeProvider',
 function($routeProvider) {
 $routeProvider.when('/', {
 templateUrl: '/templates/todo.html',
 controller: 'TodoCtrl'
 }).otherwise({
 redirectTo: '/',
 caseInsensitiveMatch: true
 })
 }]);
todoApp.controller('TodoCtrl', ['$scope', '$rootScope', 'TodoService', function($scope, $rootScope, TodoService) {
 $scope.formData = {};
 $scope.todos = [];
TodoService.getTodos().then(function(response) {
$scope.todos = response;
});
$scope.addTodo = function() {
TodoService.addTodo($scope.formData).then(function(response) {
$scope.todos.push($scope.formData)
$scope.formData = {};
});
}
$scope.removeTodo = function(todo) {
TodoService.removeTodo(todo).then(function(response) {
$scope.todos.splice($scope.todos.indexOf(todo), 1)
});
}
}]);

TodoService

Notice that we include a TodoService that we haven’t created yet. The service will communicate to our backend via a REST API we will create. Create assets/js/service/TodoService.js with the following code:

todoApp.service('TodoService', function($http, $q) {
return {
'getTodos': function() {
var defer = $q.defer();
$http.get('/todo/getTodos').success(function(resp){
defer.resolve(resp);
}).error( function(err) {
defer.reject(err);
});
return defer.promise;
},
'addTodo': function(todo) {
var defer = $q.defer();
$http.post('/todo/addTodo', todo).success(function(resp){
defer.resolve(resp);
}).error( function(err) {
defer.reject(err);
});
return defer.promise;
},
'removeTodo': function(todo) {
var defer = $q.defer();
$http.post('/todo/removeTodo', todo).success(function(resp){
defer.resolve(resp);
}).error( function(err) {
defer.reject(err);
});
return defer.promise;
}
}});

Template

Last thing we need for our front-end is the HTML template that our client will see and interact with. Here is assets/templates/todo.html that we referenced in app.js



Todo Application

{{ singleTodo.value }}

Data Flow Between the Front and Back End

One of the most challenging concepts new Sails.js developers has is determining how data flows between the front and back end. Let’s break down this process starting with the front-end using our application as an example.
Let’s say the user creates a todo from the view on the front-end. The logic that controls this part is located in the controller ($scope.addTodo function). Notice how this calls the service which uses the $http service to make an HTTP POST request to the URL http://localhost:1337/todo/addTodo
This is where Sails.js comes into play (further described below). The controller recognizes the addTodo request and in the TodoController, it communicates with the TodoService with the given todo information. Next, the service interacts with the todo model defined in Todo.js.
After updating the model, any errors or callback functions travel upstream to where the user can eventually see their newly created todo! This picture accurately sums up the communication between both, the front and back end.
frontend-to-backend-sails-angular-1200x435.jpg

Back-end

Firstly, we need to create a model that will store our todos. This object will only hold the todo value and will be stored in the Waterline ORM. All the back-end code will be in the api directory. Lastly, the data flows from the controller to service to model and back up.
We can use the sails cli to create a model and controller skeleton. Let’s do this by sails generate api Todo.
Here is the model located at api/models/Todo.js:

Model

module.exports = {
attributes: {
value: {
'type': 'text'
}
}
};

Controller

Now we need to have a controller that our service in the front-end can communicate with through the Sails.js generated API. Note that each of the functions must be the same name as the front-end service functions. Here is the controller located at api/controllers/TodoController.js:

module.exports = {
getTodos: function(req, res) {
TodoService.getTodos(function(todos) {
res.json(todos);
});
},
addTodo: function(req, res) {
var todoVal = (req.body.value) ? req.body.value : undefined
TodoService.addTodo(todoVal, function(success) {
res.json(success);
});
},
removeTodo: function(req, res) {
var todoVal = (req.body.value) ? req.body.value : undefined
TodoService.removeTodo(todoVal, function(success) {
res.json(success);
});
};
};

Service

Lastly, we have the service that is the middleware between the controller and model. In this service, we use the Waterline ORM syntax to use CRUD operations on the model. Here is the service located at api/services/TodoService.js:

module.exports = {
getTodos: function(next) {
Todo.find().exec(function(err, todos) {
if(err) throw err;
next(todos);
});
},
addTodo: function(todoVal, next) {
Todo.create({value: todoVal}).exec(function(err, todo) {
if(err) throw err;
next(todo);
});
},
removeTodo: function(todoVal, next) {
Todo.destroy({value: todoVal}).exec(function(err, todo) {
if(err) throw err;
next(todo);
});
}
};

Lift Off!

Now that we’ve finished the code let’s take a look at our application! Once again, we can run our server by sails lift.
sails-angular-todo-application-1200x374.png
And now by adding some todos, we got a nice list going! We can also remove them by checking them off.
sails-angular-todo-app-with-todos-1200x419.png

Conclusion

Sails.js and AngularJS supply extraordinary tools to implement SPAs. Additionally, using Sails.js will help create robust applications for larger applications such as enterprise applications.
Hopefully, this small project has demystified developing applications in Sails.js and AngularJS.

How to use JSON web token authentication with SailsJS


via How to use JSON web token authentication with Sails.js – console.log(‘blog’).

Using JSON webtoken authentication for consuming rest-api from your Single Page Application is pretty common these days.

In this post I’ll be helping you to use it in your Sails.js App. Well’ll be using simplest user name and password for user sign-up/in.

Prerequisite: I am assuming you have a sails app with a User model. You need to run npm i jsonwebtoken bcrypt --save to get necessary dependencies for this tutorial.

SailsJS Email/Social Auth full template


via bmustata/sails-auth-super-template · GitHub.

SailsJS Email/Social Auth full template to make it super easy to start a new project. Currently we support:

  • Local authentication with email and user signup
  • Twitter authentication
  • Facebook authentication

You can see the demo at http://sails-auth-super-template.icenodes.com

EXPRESSJS VS SAILSJS COMPARISON


via Express.js vs Sails.js Comparison | Run a Startup.

This is an overview comparing Node.JS frameworks including Express, Sails, HAPI and Lazo.js. Express is clearly the most popular currently version 4 at the time of this writing.   The next framework gaining popularity is Sails currently at version 0.10 with 124 code contributors since its inception in 2012.  Sails is not an independent framework on its own, because it uses Express for handling HTTP requests.  HAPI has 95 code contributors since 2011 but is mainly for building APIs on your server.   I am also mentioning Lazo.js because it was developed for SEO compliant websites and single-page applications are natively not SEO-friendly.

Express takes the most common tasks for a web server and makes them easier to use with less lines of code wrapping native Node.js functions.  Since there are cases where Express doesn’t abstract a needed function or doesn’t conform to some preferred convention, other frameworks take place.  Those other frameworks are not completely independent therefore you still have to use Express.  Since Express is already widely written about let’s focus on the other frameworks.  The possible main detractions of Express are the lack of  database abstraction and real-time socket communication.

How To Create an Node.js App Using Sails.js on an Ubuntu VPS


via How To Create an Node.js App Using Sails.js on an Ubuntu VPS | DigitalOcean.

Sails.js makes it easy to build custom, enterprise-grade Node.js apps. It is designed to mimic the MVC pattern of frameworks like Ruby on Rails, but with support for the requirements of modern apps: data-driven APIs with scalable, service-oriented architecture. It’s especially good for building chat, realtime dashboards, or multiplayer games.

In other words: Sails.js allows you to easily create apps with Node.js using the Model-View-Controller pattern to organize your code so it is easier to maintain. Sails.js provides various commands to automate the creation of models and controllers, saving you time and allowing you to create the app faster. (Views have to be created manually in the /views directory in the template /views/:controller/:method.ejs). You are able to use various templating languages, however EJS is the default, and it would be safest and easiest to just stick with EJS.

Sails.js also has various “adapters”, allowing you to use virtually any database you want to with your app. This gives you the maximum amount of flexibility, differing from other MVC frameworks that insist on you using MongoDB.

All of these and the fact that on deployment, all of your files are concatenated and minified means that you don’t have to spend as much time setting the main framework up to build your app on top of, as it is all ready and easy to use.

Using handlebars templates in SailsJS


via Using handlebars templates in Sails.js.

Sails makes it easy to build custom, enterprise-grade Node.js apps. It is designed to emulate the familiar MVC pattern of frameworks like Ruby on Rails, but with support for the requirements of modern apps: data-driven APIs with a scalable, service-oriented architecture.

More information can be found here on the Sails.js website.

All-in-One Data Management Stack: Official Microsoft SQL Server Adapter for sailsJS


via cnect/sails-sqlserver · GitHub.

Official Microsoft SQL Server adapter for sails.js. Tested on SQL Server 2012 and 2014, but should support any SQL Server 2005 and newer. CI tests are run against SQL Server Express. Published byc*nect.