Android Phonegap call to OpenGL ES API with no current context (logged once per thread) Error

When using Phonegap on Android I was getting this OpenGL error somewhat randomly. It seemed to be related to CSS animation. Turns out the problem was that hardware acceleration is turned off by default.

Error I was getting

call to OpenGL ES API with no current context (logged once per thread)

Add this to your AndroidManifest.xml

android:hardwareAccelerated="true"

Using authbind with forever

A few weeks ago I posted how to use authbind to runing node on port 80. This works great for simple node apps but if you need to spawn child processes that can listen on port 80 it wont work out of the box. To do this you need to use authbind --deep. Since forever doesn’t actually listen on port 80 but instead spawn a new process that listens on port 80 you need the --deep option.

So to run your node app on port 80 with forever you would run

authbind --deep forever app.js

AngularJS ng:repeate with jQueryUI Sortable

On a project I am working on I needed allow the user to reorder items in an ng:repeat. The obvious way to do this is with jQueryUI Sortable. It provides simple drag and drop sorting. The problem is getting it to play nicely with AngularJS. A quick google search came up with a stackover flow answer, but it doesn’t work with Angular v0.10.x. Here is what I ended up with or the jsfiddle.

angular.directive("my:sortable", function(expression, compiledElement){
    // add my:sortable-index to children so we know the index in the model
    compiledElement.children().attr("my:sortable-index","{{$index}}");

    return function(linkElement){
        var scope = this;            

        linkElement.sortable({
            placeholder: "placeholder",
            opacity: 0.8,
            axis: "y",
            update: function(event, ui) {
                // get model
                var model = scope.$apply(expression);
                // remember its length
                var modelLength = model.length;
                // rember html nodes
                var items = [];

                // loop through items in new order
                linkElement.children().each(function(index) {
                    var item = $(this);

                    // get old item index
                    var oldIndex = parseInt(item.attr("my:sortable-index"), 10);

                    // add item to the end of model
                    model.push(model[oldIndex]);

                    if(item.attr("my:sortable-index")) {
                        // items in original order to restore dom
                        items[oldIndex] = item;
                        // and remove item from dom
                        item.detach();
                    }
                });

                model.splice(0, modelLength);

                // restore original dom order, so angular does not get confused
                linkElement.append.apply(linkElement,items);

                // notify angular of the change
                scope.$digest();
            }
        });
    };
});

var controller = function () {
    this.list = ["one", "two", "three", "four", "five", "six"];
};

The HTML look like this

<div my:sortable="list">
    <div ng:repeat="item in list">{{item}}</div>
</div>

Using authbind to run node.js on port 80 with Dreamhost

Like everything else this requires a Dreamhost VPS. If you don’t have node.js installed yet checkout my slightly outdated guide on installing node.js on Dreamhost. It should still work just swap out the version of node.js that you need. You will also need to turn off or change the port of the web server of the VPS.

It’s a general rule that you shouldn’t run node as root, but only root can bind to ports less than 1024. This is where authbind comes in. Authbind allows non-root users to bind to ports less than 1024. Hers how:

  1. SSH into your VPS as your shell user and su into your admin account.

  2. Install authbind with sudo apt-get install authbind

  3. Configure authbind. Just swap out user with your shell user that the site runs on.

    sudo touch /etc/authbind/byport/80
    sudo chown user /etc/authbind/byport/80
    sudo chmod 755 /etc/authbind/byport/80
    
  4. Exit the admin user exit. You should now be your shell user.

  5. Configure your node app to run on port 80. In this example we will use the hello world example from http://nodejs.org modified to run on port 80. Save it as app.js.

    var http = require('http');
    http.createServer(function (req, res) {
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('Hello World\n');
    }).listen(80);
    console.log('Server running on port 80');
    
  6. Run node with authbind node app.js

****Update: Want to run forever with authbind? Checkout Using authbind with forever

(Source: debian-administration.org)

CSS Styling <input type=”file” />

Styling the <input type="file" /> tag is nearly impossible, but there is a simple solution. Don’t style it just hide it and style the <label>.

Note: You can’t display: none the <input type="file" /> because this will prevent the <label> from working.

HTML

<label id="fileLabel" for="file">
    <input type="file" id="file" />
</label>

CSS

label#fileLabel {
    // style your label
}

label#fileLabel input#file {
    width: 0px;
    height: 0px;
}

Using mongoose and connect-mongodb with Node.js

When using mongoose with connect-mongodb you need to not initialize the session store before mongoose connects. Otherwise you will get the nasty connection already open error. Always put it inside of the mongoose.connect callback.

mongoose.connect(config.db, {auto_reconnect: true, native_parser: true}, function(err) {
    var MongoStore = require("connect-mongodb");
    app.use(express.session({
        cookie: {maxAge: 60000 * 20},
        secret: "secret",
        store: new MongoStore({db: mongoose.connection.db})
    }));
});

I finally made the move from TextMate to vim

and I wish I had done it a long time ago. I will link to the resources I used when I get around to it, but until then I started with vimtutor and googled my way from there.

MacVim is a great tool but it pays to start with plain old command line vim. You will want to use iTerm instead of Apples Terminal.

I put my .vim files on github if your interested.

Mobile Analytics