Saturday, December 12, 2015

Angular Charts and the "undefined" draw error on single series line charts

I've been recently working with Ionic and my app needed a chart. Also, been listening to way too much Tricot and Toe.

This chart requirement lead me to angular-chart which is based on the excellent chart.js library. My use case was simple. I needed a line chart to visualize various "single" series data. And this is where I encountered this "undefined" draw (and update) functions.

For context, this how my data looked.

{
   id: 0,
   labels: ['13:00', '13:15', '13:30', '13:45', '14:00', '14:15', '14:30', '14:45'],
   series: ['Stat #1'],
   data: [28, 30, 29, 32, 70, 79, 89, 98 ]
}

The important part here is the data array. This was the one causing the problem after I traced it to a closed issue in github. To fix this was to just turn the flat data array into a 2-dimensional array and poof the error is gone.

{
   id: 0,
   labels: ['13:00', '13:15', '13:30', '13:45', '14:00', '14:15', '14:30', '14:45'],
   series: ['Stat #1'],
   data: [[28, 30, 29, 32, 70, 79, 89, 98 ]]
}

I can now see my chart.

Wednesday, December 2, 2015

A tutorial on how to use the Tapestry-Security module Part 2

We pick up where we left off.

We start with our AppModule and configure our security service to use our "custom" realm.

    
    // @see http://tynamo.org/tapestry-security+guide
    @Contribute(WebSecurityManager.class)
    public static void addRealms(Configuration configuration, @InjectService("MiscAppRealm") AuthorizingRealm userRealm) {
        configuration.add(userRealm);
    }

With this we then update our MiscRealm.java code:
    
  @Inject
  private UserMembershipDAO umDAO;    

  public MiscAppRealm() {
        super(new MemoryConstrainedCacheManager());
        setAuthenticationTokenClass(UsernamePasswordToken.class);
        setCredentialsMatcher(new MiscRealmCredentialMatcher());
  }

  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
        if(pc == null) throw new AuthenticationException("PrincipalCollection was null, which should not happen");
        
        if(pc.isEmpty()) return null;
        
        if(pc.fromRealm(getName()).size() <= 0) return null;
        
        String loginName = (String)pc.fromRealm(getName()).iterator().next();
        if(loginName == null) return null;
                
        AppUsers user = umDAO.FindAppUsersByLoginId(loginName);
        
        if(user == null) return null;
                
        Set roles = new HashSet<>(user.getRolesList().size());
        user.getRolesList().stream().forEach((role) -> {
            roles.add(role.getDescription());
        });
        
        System.out.println("Roles: " + roles);
        
        return new SimpleAuthorizationInfo(roles);
  }

  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken at) throws AuthenticationException {                
        UsernamePasswordToken token = (UsernamePasswordToken)at;
        
        String username = token.getUsername();
        
        if(username == null){
            throw new AccountException("Null usernames are not allowed by this realm");
        }
        
        AppUsers user = umDAO.FindAppUsersByLoginId(username);
                
        if(user.getIsLocked()){
            throw new LockedAccountException("Account: " + username + " is locked.");
        }
         
        return new SimpleAuthenticationInfo(username, user.getEncodedPassword(), new SimpleByteSource(user.getPasswordSalt()), getName());
 }

We then move on to our custom credential matcher (MiscRealmCredentialMatcher.java) which extends from SimpleCredentialsMatcher. The thing there is overriding the doCredentialsMatch() method on it. You need to remember though is that the UserMembership table stores the encrypted password instead as plain text. You'll get the idea when you see the jasypt documentation.

@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
     
     AppUsers target = FindAppUsersByLoginId(UserId);
     String encryptedPassword = target.getPassword();
        
     BasicPasswordEncryptor passwordEncryptor = new BasicPasswordEncryptor();
        
     return passwordEncryptor.checkPassword(String.valueOf(token.getPrincipal()), encryptedPassword);
}

The last part of the puzzle is how we handle the Login form when we submit it. The Tynamo-Security's own code is helpful here.

    
void onValidateFromLogin() throws ValidationException {
        
     Subject currentUser = securityService.getSubject();
                
     if(currentUser == null){
         throw new IllegalStateException("Subject can`t be null");
     }
        
     UsernamePasswordToken token = new UsernamePasswordToken(loginId, password);
     token.setRememberMe(rememberMe);
        
     try {
          currentUser.login(token);
            
     } catch (UnknownAccountException e) {
         login.recordError(loginIdField, "");
         login.recordError(passwordField, "Invalid user name or password.");
     } catch (IncorrectCredentialsException e) {
         login.recordError(loginIdField, "");
         login.recordError(passwordField, "Invalid user name or password.");
     } catch (LockedAccountException e) {
         login.recordError(loginIdField, "Account is Locked. Please see Administrator");
     } catch (AuthenticationException e) {
         login.recordError(loginIdField, "");
         login.recordError(passwordField, "Invalid user name or password.");
     }
}

Object onSuccessFromLogin() throws MalformedURLException, IOException {
    if (StringUtils.hasText(successURL)) {
        if ("^".equals(successURL)) {
             return pageRenderLinkSource.createPageRenderLink(componentResources.getPage().getClass());
        }
        return new URL(successURL);
    }

    if (redirectToSavedUrl) {
         String requestUri = loginContextService.getSuccessPage();
         if (!requestUri.startsWith("/") && !requestUri.startsWith("http")) {
             requestUri = "/" + requestUri;
         }
         loginContextService.redirectToSavedRequest(requestUri);
        return null;
    }
    return loginContextService.getSuccessPage();
}

What's left is to annotate the pages to secure.

Edit: smallish changes to code

Monday, November 30, 2015

A tutorial on how to use the Tapestry-Security module Part 1

It often bothered me how many times I've been answering questions from my students (and Stack) this question: "How do you use Tapestry-Security?"

Actually, Tynamo already wrote a guide but some are actually having a hard time figuring it out. They are confused by the database part and how it connects to the authentication and authorization parts. So this is where I come in and since this is should be pretty long post, I'm breaking it into two parts. Also, I'd be working on the assumption readers:
  • Have working knowledge of Tapestry5
  • Can get a Tapestry5 DAO service going
  • Basic understanding how Shiro works (or at least read the tutorial); YOU NEED TO UNDERSTAND SHIRO because Tapestry-Security is based on it.
  • Are OK with me using jasypt lib for encryption; I know it's not the best so chill your titties, we need to make work first THEN we'll deal with a much stronger encryption procedure.
To get started,

Open your POM.xml file and add the Tapestry-Security and Jasypt modules as a dependency.

<dependency>  
  <groupId>org.tynamo</groupId>  
  <artifactId>tapestry-security</artifactId>  
  <version>0.6.2</version>  
</dependency> 

<dependency>  
  <groupId>org.jasypt</groupId>  
  <artifactId>jasypt</artifactId>  
  <version>1.9.2</version>  
</dependency> 

Rebuild your project after to get the module.

Once that's out of the way, we should start creating a Realm. We are making an Authorizing Realm, which authenticates subjects (or users) AND authorizes them with either Roles or Permissions. Here's a sample:

public class MySecurityRealm extends AuthorizingRealm {

    @Inject
    private UserMembershipDAO umDAO;
    
    public MiscAppRealm() {
        super(new MemoryConstrainedCacheManager());
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken at) throws AuthenticationException {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}

You then need to configure your WebSecurityManager to use this realm. The WebSecurityManager service is something that Tapestry-Security module adds. Also, don't worry about the unimplemented methods in the realm. We're going to fix that on the next post.

Monday, October 12, 2015

Tapestry5, JPA 2 and Hibernate

The documentation for Integrating JPA found on the Tapestry5 website was lacking.
  1. It doesn't tell you that you have add the Tapestry-jpa dependency in you project POM
  2. It uses EclipseLink
  3. Explicitly tell you to use JPA 2.0 NOT JPA 2.1;
So, I had a few problems to fix after reading and following the docs. With much tinkering with my Tapestry5 (5.4-beta-35) project, I figured out:
  1. To add the Tapestry-jpa dependency
    <dependency> <groupId>org.apache.tapestry</groupId> <artifactId>tapestry-jpa</artifactId> <version>5.4-beta-35</version> </dependency>
        

  2. Hibernate 4.2 instead of EclipseLink
    <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>4.2.20.Final</version> </dependency>
  3. Edit the persistence.xml header so it reads version=2.0 instead of 2.1. This is because my Netbeans IDE can generate the persistence.xml file but defaults to 2.1 version instead of 2.0.
And if you get a javax.persistence.PersistenceExceptionUnable to build EntityManagerFactory error during the build, you probably didn't add a hibernate.dialect property in your persistence.xml configs.

Thursday, October 8, 2015

Tapestry5, JPA, Netbeans and a FilerException

Tapestry5.4 supports JPA out of the box which is nice. Also Netbeans supports JPA, doubly nice. Now if you're using 2 or more Persistence Units, you have probably encountered a FilerException when you try to compile or run your project. This shouldn't be a problem if you're using only single Persistence Unit. I suspect the fix would be the same if you encounter the same exception.

java.lang.RuntimeException: javax.annotation.processing.FilerException: Attempt to recreate a file for type {myclass}

The {myclass} here is always an entity class.

I think, a secondary symptom of this is if all your entity classes are all in a single package. This should be the case if you're doing a standard Tapestry5 web application.

The fix to this is to edit the Persistence Unit and add a  property and explicitly declare the entity classes on the Persistence Unit.

<persistence-unit name="PayrollPU" transaction-type="RESOURCE_LOCAL">  
   <provider>org.hibernate.ejb.HibernatePersistence</provider>  
   <class>cu.ictso.miscapps.entities.Departments</class>  
   <class>cu.ictso.miscapps.entities.Employee</class>  
   <class>cu.ictso.miscapps.entities.Groups</class>  
   <class>cu.ictso.miscapps.entities.ViewAttendance</class>  
   <exclude-unlisted-classes>true</exclude-unlisted-classes>  
   <properties>  
    <property name="javax.persistence.jdbc.url" value="jdbc:sqlserver://localhost;databaseName=DTR-Payroll2;Integrated Security=false"/>  
    <property name="javax.persistence.jdbc.user" value="PayMaster"/>  
    <property name="javax.persistence.jdbc.driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>  
    <property name="javax.persistence.jdbc.password" value="123456"/>  
    <property name="javax.persistence.schema-generation.database.action" value="create"/>  
   </properties>  
 </persistence-unit>  

Here's an example Persistence Unit.


Tuesday, September 29, 2015

Wat!? HTML is now an application framework? I'm calling bullshit!

You wish it was bullshit, but no. HTML, since HTML5 has provided full-blown component-oriented solutions. Stuff like the Shadow DOM specs, media-queries, validation and error handling are just the tip of this iceburg. New stuff is being added to HTML everyday.

A good example I can give is the way how text (or code) completion is done in HTML5 - let's say a "browser" list textbox. The old way of doing this would be a choke-full of JavaScript. We can use a datalist tag element instead.

<input type="text" name="browserSelect" 
    list="browserList"/> 

<datalist id="browserList">  
   <option value="IE">  
   <option value="Firefox">  
   <option value="Chrome">  
   <option value="Opera">  
   <option value="Safari">  
</datalist>  

Of course, you could further refined this with a dash of JavaScript like say Angular or Knockout.

Now if only companies drop IE6 or IE8. zzzzzz.

Friday, September 4, 2015

AngularJS and the case of "but I don't want to rewrite my event listeners." (also I have directives)

Well, damn. Shit son.....

Calling event listener functions outside of AngularJS is not that hard. There might be a "strong" discussion on how to do this but that's a matter of style. That is a whole other bowl of soup.

We can fix this in a jiffy and we just have to keep in mind that Angular elements are accessible via JQLite.

We start with our directive to which we will then attached a listener function.

// app.js
angular.module('myApp', [])
   .directive('myDirective', function myDirective () {
        return {
            restrict: 'AEC',
            link: myDirectiveLink
        }
   });

function myDirectiveLink (scope, element, attrs) {
    var someDOMElement = element[0];
    someDOMElement.addEventListener("click", myDirectiveEventListener, false);
}

function myDirectiveEventListener () {
    // Handle the event here
   // This could be an existing listener somewhere in a different source file
}

Now all we need is to declare 'myDirective' in a valid DOM element in our view. It will respond to a click event that will be handled by the 'myDirectiveEventListener' function.

Tuesday, September 1, 2015

A web developer's stake in the Battle of the frontends

It use to be easy as pie being a frontend dev or engineer. You either roll your own frontend framework that doesn't use tables for layouts or pick something with a grid like 960.gs and you're good. That was like 4-5 years ago. Now there's a long list of front-end frameworks to choose and all of them have fanboys. It's a mess.

For me, there are four choices that really make sense. It makes sense because I've used them in one form or another. Also, all these frameworks are responsive by default so they support mobile development also not just standard web.

  • Material Design Lite - If your going Google then this is framework for you. The thing with this is that it doesn't rely on any JavaScript. This is the "truest" implementation of Material Design if you're making the argument for say, Material Bootstrap.
  • MetroUI (and Office-UI-Fabric) - This is for those who like tiles (MetroUI). Fabric for web apps that look like Office365 apps. You don't have to be knee deep in building Window apps for web and phone to be using this - ie. You don't need Visual Studio or have a pricey WinDev account. It's open-sourced - Surprise! Surprise! It's built using Less; Curious though, no Typescript.
  • Foundation by Zurb - Foundation is staple for those rabid SaSS fans and unlike the first two, this framework comes with everything even the kitchen sink. Heck, you can even make your own plugins. The strength of Foundation is its more malleable than Material or Metro but that's offset by the fact it's also has more moving parts. Testing much?
  • Bootstrap - Twitter Bootstrap, the preferred frontend framework for the design impaired developer. Popular (maybe) and easy-to-use (arguable) it's  not bad looking even if you're just using the base CSS. Sure, you can customize it with your choice of SaSS or Less but if your in a hackathon you just don't care and use a theme from one of many websites making free bootstrap themes like this one
For us web devs, we treat these 4 frameworks as the same thing, 4 different libraries that do the same thing. But we won't tell the UX guys that, they'd go ape shit.

Thursday, May 21, 2015

Ubuntu 15.04, OpenFire and "Unable to validate certificate" problem

While Upgrading to OpenFire 3.10 from 3.9, I encountered this error on my clients running either pidgin or empathy. I'm running OpenFire with a mix of Empathy and Pidgin clients on a corporate LAN.

Took me a bit for figure out that the certificates isn't the problem but the names. Here's the steps, I did:

1. Check your OpenFire server settings and look for the xmpp.domain value. Remember that value.

2. In the clients, flush the certificates folder; I'm running linux so that folder is ~/.purple/certificates/. In hindsight, I think this step can be skipped because I think Empathy or Pidgin overwrites the folder with the most current certificate.

3. Make sure clients don't log in using the ip address. So no accounts in the form of, username@10.209.70.19 but rather username@xmpp.domain. (so if your xmpp.domain is appsvr1 then the username is username@appsvr1). 

4. Edit the host file to satisfy the FQDN requirement. Assuming that your OpenFire server is at 10.209.70.19 and the xmpp.domain is appsvr1, the you have a host entry of 10.209.70.19 appsvr1. You basically alias it.

My users now can bother me again. 

Haiz...


Monday, May 4, 2015

Bootstrapping the View Parts

Time to add a face to our project. So, we break out our favorite framework for the designed-impaired programmer, Bootstrap!

Download the stuff and put it in the public/ folder. I made a bootstrap folder in my public folder to keep it organize. Don't forgot to also get jquery. Bootstrap doesn't work without jquery. This is the easy part.

The next part is kinda hit or miss: Jade

Nodejs with Express uses a templating engine to make views. There are a couple of options but jade is the default. I say hit or miss is because some take to Jade like ducklings to water. Some of you might not be ducklings. 

Here's a sample:

nav(class='navbar navbar-default navbar-static-top')
    .container
        .navbar-header
            button(type='button', class='navbar-toggle collapsed', data-toggle='collapse',                    data-target='#navbar', aria-expanded='false', aria-controls='navbar')
                span(class='sr-only') Toggle navigation
                span(class='icon-bar')
                span(class='icon-bar')
                span(class='icon-bar')
            a(class='navbar-brand', href='#')= title
        div(id='navbar',class='navbar-collapse collapse')
            ul.nav.navbar-nav
                li.active
                    a(href='#') Home
                li
                    a(href='#') About
                li
                    a(href='#') Contact

Jade templating language is quite terse to write compared to raw HTML. It also has a few fun parts like includes, conditionals and mixins.

In the Views/ folder, I made a shared folder and move the common stuff like the layout and navbars. This way I can compose the view like lego bricks AND that's where the fun starts.

Clone the repo at Github.

Saturday, April 18, 2015

Finish the REST (Part 2) with Fiddler debugging and testing

We are doing three things for this part: (1) finish coding the REST api (2) Debug with Fiddler (3) Write Frisby test against our API.

Finishing the REST api is the easy part. Make a folder with the path api/v1/ inside the routes folder. Inside the api folder is another folder called v1. I do this just out of habit. APIs will change in even in a production environments. When that happens, I just add a v2 folder. It's just a cheap and easy way to future proof REST API endpoints.

After the folders, create a posts.js file inside.

var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');

// Get the model
var post = mongoose.model('Post');

// GET /api/v1/posts - GET ALL
router.get('/', function (req, res) {
    post.find({}, function (err, posts) {
        res.json(posts);
    });
});

// GET /api/v1/posts/:post_id
router.get('/:post_id', function(req, res) {
    post.findById(req.params.post_id, function(err, post) {
        if (err) res.send(err);

        res.json(post);
    });
});

// POST /api/v1/posts
router.post('/', function(req, res) {
    var newPost = new Post();
    newPost.title = req.body.title;
    newPost.body = req.body.body;
    newPost.author = req.body.author;
    newPost.published = req.body.published;

    newPost.save(function(err) {
        if (err) res.send(err);
        res.json({ message: 'Post created!' });
    });
});

// PUT /api/v1/posts
router.put('/', function(req, res) {
    post.findById(req.params.post_id, function(err, post) {
        if (err) res.send(err);

        post.title = req.body.title;
        post.body = req.body.body;
        post.author = req.body.author;
        post.published = req.body.published;
        post.meta.favs = req.body.favs;
        post.meta.dvotes = req.body.dvotes;
        post.meta.uvotes = req.body.uvotes;

        post.save(function(err) {
            if (err) res.send(err);

            res.json({ message: 'Post updated' });
        });
    });
});

// DELETE /api/v1/posts/:post_id
router.delete('/:post_id', function(req, res) { 
    post.findByIdAndRemove(req.params.post_id, function(err, post) {
        if (err) res.send(err);

        res.json({ message: 'Post deleted!' });
    });
});

module.exports = router;

The whole thing should be fairly easy to figure out since this is the actual CRUD stuff.

Run the project and we should see our web page. Now we move to Fiddler to see around our API. Remember, you can just Postman instead of fiddler.

Start here: The Composer Tab in Fiddler
After you've open Fiddler, just go to the composer tab and add the API url you're interested in. Don't forget the HTTP verb. Press the Execute button on the top right to see the results.

You'll be able to go to the other tabs to see a lot of information.

The Inspectors tab contents is what we are interested in. This is where we see what's inside the reply from our API (or lack thereof if that is what we are expecting).

And finally, tests for our REST API endpoints. I wanted to add tests for our API to ensure behavior and for regression. It just makes sure I don't break the API as we continue working on this little project of ours.

We will be using the Frisby framework. Frisby is made to test REST API on node.js projects.

So, we install Frisby. Open a terminal, navigate to the project folder and type in:

npm install -g --save frisby

That should install the latest frisby version and save it a dependency in our package.json file. When frisby installed, create a folder named spec and inside that another folder named api. Inside these folders, a javascript file named posts_spec.js.

var frisby = require('frisby');
var baseURL = 'http://localhost:1337/'; // just replace if on live server

frisby.create('Status 200 for GET /api/v1/posts is returned')
    .get(baseURL + 'api/v1/posts')
    .expectStatus(200)
    .toss();

frisby.create('Status 200 for GET /api/v1/posts/:id')
    .get(baseURL + 'api/v1/posts/5525f1e3f6a7f3a00b234a09')
    .expectStatus(200)
    .expectJSON({ 'author': 'jaypax' })
    .toss();


Here we have two tests. Feel free to add more.

Now we just need to run it for which we need jasmine-node.

npm install -g --save jasmine-node

After NPM is done, you should be able to run the command in your terminal: jasmine-code spec/api/


Friby results after running the test 
By the way, you need the project to be running in order to run the test.

You basically have two terminals open: 1 terminal running the project and other terminal to run the test from.

Clone the code at the github repo.

Wednesday, April 15, 2015

Coding the REST services (Part 1) - The model

Coding up the REST services part is similar to coding up the CRUD parts for you traditional desktop application. The difference is quite subtle because you'll be also dealing with HTTP verbs - POST, GET, PUT, DELETE. We are going to make the data model first so we have something to interact with.

First step is creating a connection. In our case, we are connecting to MongoLab, so in your app.js file you add the following:

// our libs
var mongoose = require('mongoose');
var uriUtil = require('mongodb-uri');

// our connection function
var connectToMongoLab = function () {
    var username = process.env.MongolabUsername;     // external var for our username
    var password = process.env.MongoLabPassword;     // same for the password

    var mongolabUri = "mongodb://" + username + ":" + password + "@ds035448.mongolab.com:35448/dbhaxspace";
    var mongooseUri = uriUtil.formatMongoose(mongolabUri);
    var options = {
        server: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } },
        replset: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } }
    };
    mongoose.connect(mongooseUri, options);  // connect us to the db with these options
};

connectToMongoLab(); 

mongoose.connection.on('error', console.log);   // if error in connecting to db, dump errmsg to console
mongoose.connection.on('disconnected', connectToMongoLab); // if disconnected just reconnect

// load models
fs.readdirSync(__dirname + "/models").forEach(function(file) {
    if (~file.indexOf('.js')) require(__dirname + '/models/' + file);
});

This should be added before the routes portions. Now for the actual model.

We're using Mongoose to model our data. Think Entity Framework if you're a C# guy, Hibernate (or JPA) if Java and SQLAlchemy for the python guys. (No, PHP gets not love. #Dealwithit)

Create a folder called Model and create a new javascript file in that folder. In our project, our model is called post and it's declared in the post.js file.

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var PostSchema = new Schema({
    title: { type: String, default: '' },
    author: { type: String, default: '' },
    body: String,
    published: Boolean,
    date: { type: Date, default: Date.now },
    geoloc: {
        latitude: { type: Number, default: 0 },
        longitude: { type: Number, default: 0 },
        label: { type: String, default: ''} 
    },
    meta: {
        uvotes: { type: Number, default: 0 },
        dvotes: { type: Number, default: 0 },
        favs: { type: Number, default: 0 }
    }
});
// methods
PostSchema.method({
    findAll : function(cb) {
        return this.model('Post').find({}, cb);
    }  
});
// statics
PostSchema.static({

});
// register
mongoose.model('Post', PostSchema, 'posts');

Mongoose schema's have some pretty nifty features like types, methods and statics that can be part of the model. The whole thing then wraps up when you call the mongoose.model() function to register the model.

Once we have our model registered. We can then call our model into any part of the app.

var mongoose = require('mongoose');
// Get the model
var post = mongoose.model('Post');

We will pick this up on part 2 where I actually show you the REST parts.

Thursday, April 9, 2015

Node is up: hello world

This "Hello world" thing has a long history in programming but very few student programmers really understood it purpose or assumed wrongly what it's purpose.

The "hello world" program is the first thing done on learning new programming languages and it's also the first program done when trying out a newly setup environment to make sure everything is working. This is what we are doing now.
  1. Start by creating our "Basic Node.js Express 4 Application" in Visual Studio.


  2. Run it, point your browser to http://localhost:1337/ and see our web app running. If it runs we are golden and continue to the next set of steps. If not, then you better get to fixing.

  3. Now that we have a known working node.js app. We should commit this to a source repo like github or bitbucket. At the start of this tutorial I did mention I'll be using SourceTree to manage this but you can go old school and use a terminal if you feel that SourceTree is creepy.



    So create a new repository and don't commit any files yet.

  4. We have to create a .gitignore file so we don't commit temporary or intermediate files. We will be using this .gitignore file. So just go to the root of the new repo and copy that .gitignore file there. SourceTree should be able to pick it the new file and use it, "ignoring" files listed in the gitignore..

    Don't forget to commit the files and push it into your repo. Read this if you need more details about pushing into a remote repo.
Now for the lazy, you can instead clone the repo here. Or if you're just lost then follow this tutorial on how to use git.

Don't be afraid to play around with the code. If you screw up, just delete the offending project folder and clone the project again. After cloning, you'll be good again.

Friday, April 3, 2015

Dude bro, JavaScript's bound functions are stupid

Too many times I've come upon this comment or question, "What happen to 'this'?" If you haven't caught on JavaScript is a fucked up language. It has quirks that you have to work around. One of these is it's JavaScript's Scope behavior which is the root of "What happen this to 'this'?".

Let's take a simple example from Java.

public class Person {
    public String fname;
    public String lname;
    public String getFullName() {
        return this.fname + " " + this.lname;
    }
}

In this case, the getFullname method is bound to each instance of a Person object so when I say:

Person dude = new Person();
dude.fname = "Jay";
dude.lname = "Pax";
dude.getFullName(); // returns "Jay Pax"

I know that this in the getFullname() refers to dude. The binding of this in which I'm running getFullName() is dude, a specific instance of Person.

In JavaScript , functions don't behave like this. They don't have bound methods. In fact, they can be unbound and rebound at the coder's whim.

For example, if I have:

var getFullName = function(){
    return this.fname + " " + this.lname;
}

There is no obvious context that this should refer to.
So now let's go a step futher and say I wrote something like this:

function foo(){
    return this.fname + " " + this.lname;
}
var getFullName = foo;

That's not much different. We don't know what this is referring to exactly. So getFullName still doesn't have a clearly-defined this binding.

So let's give it one:

var dude = {
    fname: "Jay",
    lname: "Pax",
    getFullName: function(){ 
        return this.fname+ " " + this.lname;
    }
};
dude.getFullName(); // returns "Jay Pax"

Well now! That's starting to make sense. Until you do something like this:

var doAThing = dude.getFullName;
doAThing(); // returns "undefined undefined"

Waaaaattttt......

You see, when I pointed the variable doAThing at dude.getFullName, I pointed it a the function of getFullName NOT the object dude. So we lost the this binding in the process.

I know it's fucked up but it's fixable you'll have to use Function.bind.

Tuesday, March 31, 2015

My summer 2015 MEAN project: Setting up

So let’s get started. my set up:
  1. Visual Studio: community edition with Nodejs tools. I can hear the WTFs from here. Why? Because it’s an excellent IDE for node development, we can get it for free and I know a couple of people who go into a blind rage when I something from the evil empire. Yes, let the hate flow through you.

    But seriously, any text editor will do if you don’t to use VS.
  2. Fiddler. We need something to debug and test our REST API. We could just use a web browser like…...IE (hehehehe) but sometimes we need to drill down to the raw parts to debug. Besides, it’s another free software.

    Postman can be an alternative.
  3. Sign up for Azure. This is the iffy part because you need a credit card. Azure does have a generous free trial and a teacher/student program via DreamSpark. But if Azure rubs you the wrong way then you can do a local VM like turnkey. It’s the same thing. But if you really, really must use something else then there's Openshift or DigitalOcean or Heroku or Amazon. All these services have free trial accounts in some form.
  4. Github via SourceTree. Someone once said, “you’re not a developer unless you have github.” But if you go all ghetto on me, there’s Bitbucket or Codeplex.

    As for SourceTree, it’s another free software for code repos. It works with Git and Mercurial repos. You could opt for a the command line, I won’t judge you. I mean, I can’t judge someone on how they enjoy pain.
  5. Nodejs and NPM stuff. Install node is straight-forward affair. The stuff you have to do after sort of isn’t. The tribe of terminal user will rejoice this part. 
    • ExpressJS. We need it because a node app isn't much without express
    • bower. We need bower because I’m lazy and don’t want to the whole dance of google, download, unpack and copy for web stuff. 
    • mongoose. Because MongoDB database.
  6. Mongolab account. Mongolab does MongoDB as a Service and they have a free plan with 500MB on it to try out. If you don’t want to then you can install MongoDB on your PC or use a VM.
And that’s it. We got our dev environment set.

Sunday, March 29, 2015

My summer 2015 MEAN project: Dormmetita

Dormmetita. That's the name of the app we are building.

I asked a question over at the CDO-ITG FB page a couple of weeks ago what would the community like to read or do over the summer. I had a couple of options for Java, Node and Python. The overall winner though was nodejs. So for the summer I'm doing a MEAN tutorial to build an old app that a couple of guys "brainstormed" about a year back named Dormmetita. Right, +Romar Mayer Micabalo+Paul Michael Labis+Raven Duran?

Technically it's "Dorm me, tita." which is an app to find and post dorm rooms, apartments for students localized to my city, Cagayan de Oro which is a university town. We might throw in reviews but let's keep it simple for now. We can make up stuff as we go.

 I've broken down the tutorial in these topics:
  1. Setting up 
  2. Node is up: hello world
  3. Coding the REST services (Part 1) - The Model
  4. Finish the REST (Part 2) with Fiddler debugging and testing
  5. Bootstrapping the view parts 
  6. Add Angular to the page
  7. Deploy to Azure, because free is nice

So bookmark this post to follow. 

Friday, February 27, 2015

Netbeans 8 on 4k displays

Running Windows 8 (or 8.1) on a 4k display is pretty sweet once you get your settings right. Even the Metro apps run good on a 4k display.

The problem here is the 3rd party apps like Netbeans 8. They don't show right because of scaling issues. Fortunately is can be easily fixed by doing a bit of editing a text file.

In order for Netbeans 8 to display right in 4k resolution displays on Windows 8 you have to:

  1. Open for edit netbeans.conf file. It should be located at c:\Program Files\Netbeans 8.0\etc folder 
  2. Change -J-Dsun.java2d.dpiaware=true to -J-Dsun.java2d.dpiaware=false
And we should be set.

Monday, February 9, 2015

Stop asking me which one: Flask vs Web.py

I'm writing this entry because I've been asked the same question at events and on the internet too many times: "Which one to use, flask vs web.py?" I'm also doing this to clarify my reasons on why I like Flask better than web.py.

Disclaimer: this is more of an personal opinion rather than a more true technical comparison.

Flask and Web.py are these Python micro-architectures for building web sites and applications. Django is also a Python framework for building websites but it's whale huge so Django is out.

Age
The age of the framework matters because it helps you "find stuff" for it; find stuff, I mean like StackOverflow pages, blog entries, github projects and such. Also it makes for a good chance that someone already has solved your problem and was good enough to post it somewhere on the web.

Web.py is older and Flask is a bit more recent.

I like new.

Code-wise
Programmers and coders eventually develop a particular "taste" on how to write or organize code. This is another bias of mine because I prefer how Flask's code looks vs Web.py's.

Let's take both framework's "hello world" examples.

This is Flask's way:

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run()

This is Web.py's way:

import web
        
urls = (
    '/(.*)', 'hello'
)
app = web.application(urls, globals())

class hello:        
    def GET(self, name):
        if not name: 
            name = 'World'
        return 'Hello, ' + name + '!'

if __name__ == "__main__":
    app.run()

I like annotations better than route lists but that's just me.

Use cases
I have a pretty simple use case because I only run these things in a Google app engine instance. Both flask and web.py are supported by GAE.

Here's a flask starter for GAE and here's the web.py cook book page for GAE.

I still like Flask.

In the end
Personally, I think the question is relatively moot since both micro-frameworks do roughly the same thing. Although, web.py is older it is still actively developed and it's community is still ticking. Flask is newer but it's still a bit rough around the edges.

I'm a Flask kind of guy.



Monday, January 26, 2015

Dropping Bootstrap for Patternfly

Bootstrap is a godsend to single developers who suck at design. It had everything from components to simple animations for that eye candy.

And then things messy when that developer finds "themes" for bootstrap like the free ones over that bootswatch or the high-end stuff over at wrapbootstrap. I'm not saying these things are bad but all to often developers don't have the "design disciple" to use these themes. As developers, we have this tendency to use all the features, colors, suggested layout, etc.; user experience not withstanding. I'm guilty of this. We end up with this "soup" of a website or web app that's full of fancy animations and inconsistent visual design.

I think the fix for this is a set of guidelines that developers can happily follow and this is where patternfly comes in. Pattenfly is built on bootstrap so developers already using bootstrap will have no problem using it.

The nice things with Patternfly:

  1. No more trawling the net for lay-outing advice (https://www.patternfly.org/wikis/layout-templates/)
  2. Common design patterns done (https://www.patternfly.org/wikis/patterns/loginlogout/)
  3. Shitload of widgets, visual widgets and fonts
  4. And it's free; github here.