js: angular touch delay/lag on mobile

I had built InviteAgain.com to seamlessly work on mobile devices. This was the first project in Angular where I wasn’t handling my own mouse/touch up and down, and I just planned to rely on ng-click, and default mouse/touch behaviors to handle the table scrolling.

I was getting what felt like bad lag when running the app on mobile. The connection to the database would load and refresh data immediately, but the user interaction, ie touch, was taking forever to respond. So after some head bashing, I managed to learn the hard way that the library angular-touch, made by angular, is pretty much a requirement for mobile if you are going to rely on ng-click, and not handle your own mouse up and down.

Angular-touch modifies the standard ng-click to remove a 300ms delay mobile browsers otherwise impose while waiting to see if the user is going to double tap. Problem solved!

js: parsing csv files in angular with papa parse

I’ve been trying to embrace/balance using more libraries and less native code. The CSV parsing I needed to do on InviteAgain.com was a great candidate. I found PapaParse. Perfect. Simple javascript class that can handle all use cases via a single settings object.

I setup an Angular directive and template that I can plug in anywhere to get a custom file input UI. That UI contains another directive linked to the file input event. On file input angular hands the csv off to the Papa object. I tell it the data has headers, to use web workers, and to run $apply() on the scope after it’s completed parsing the file. Papa hands me back a javascript object with all the csv’s key/value pairs. Done.

.directive('onReadFile', function ($parse) {
  return {
    restrict: 'A',
    scope: {conSec: '=', current: '='},
    link: function(scope, element, attrs) {
      element.on('change', function(onChangeEvent) {

      var file = (onChangeEvent.srcElement || onChangeEvent.target).files[0];

       Papa.parse(file, {
          header: true,
          worker: true,

          complete: function(results) {
            if(scope.conSec.name){
              scope.conSec.fileInput.err = results.err;
              scope.conSec.fileInput.data = results.data;
              scope.conSec.fileInput.meta = results.meta;
              // Need to force the update
              scope.$apply();
            }
          }
        });
      });
    }
  };
})

.directive('fileInput', function(){
  return {
    restrict: 'E',
    scope: {conSec: '=', current: '='},
    templateUrl: "../templates/fileInput.html"
  };
});

devops: mysql server on azure ubuntu vm

Full disclosure, there are a lot of tutorials for this on the azure website. I just found that every one of them had either enough errors, or enough missing pieces, that it made it impossible to get setup correctly unless you knew what you were doing, so hacked quite a bit of them together.

Go to manage.windowsazure.com
Click Virtual Machines > New > From Gallery
(I’m using Ubuntu server 14.04 LTS)

Virtual Machine Name: yourvm
(This will become the address in yourvm.cloudapp.net)

New User Name: yourvmusername
(this will be used anytime you need to access the vm)

UNCHECK: UPLOAD COMPATIBLE SSH KEY FOR AUTHENTICATION
(you are welcome to handle keys yourself, I’m just going for passwords)

CHECK: PROVIDE A PASSWORD: yourvmPassword!
(this will be the password to access the vm)

SET: create new cloud service

CHECK: VM agent

COMPLETE

Open Terminal. Connect Via SSH:
ssh yourvmusername@yourvm.cloudapp.net -o ServerAliveInterval=180
//You will see the following, enter yes, then your vm password:
The authenticity of host 'yourvm.cloudapp.net (255.255.255.255)' can't be established.
Are you sure you want to continue connecting (yes/no)? yes

Warning: Permanently added 'yourvm.cloudapp.net,255.255.255.255' (RSA) to the list of known hosts.
yourvmusername@yourvm.cloudapp.net's password:
yourvmPassword!

Welcome to Ubuntu 14.04.2 LTS (GNU/Linux 3.16.0-43-generic x86_64)
//a bunch of text
//then you'll be at the prompt: yourvmusername@yourvm:~$

Update the VM:
sudo apt-get update
(could take a couple of minutes, bunch of text)
//back to prompt

Install MySQL Server on the VM:
sudo apt-get install mysql-server
//bunch of text
Do you want to continue? [Y/n] Y

UI popup for password for root user on mysql server: yourSQLpw
(this will be how you initially access the mysql server, via un: root, pw: yourSQLpw)
//Confirm it, then back to terminal, lots of text spam, even some things that look like errors or warnings “sent invalidate” and “using unique option prefix” just move on.
//back to prompt

Install MySQL Client on the VM:
sudo apt-get install mysql-client
//bunch of text
//back to prompt

Test if the Service is Running:
sudo service mysql status
//should see: mysql start/running, process etc

Now Open Port 3306 on the VM:
sudo iptables -A INPUT -i eth0 -p tcp -m tcp --dport 3306 -j ACCEPT

Test that the Port is Open:
sudo netstat -anltp|grep :3306
//you should see something like:
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 3259/mysqld
(3306 in red, that doesn’t mean bad, just that it found that number)

SSH Tunnel from 3307 to 3306:
(Now we create a tunnel on the VM that takes public connections from 3307 and locally sends them to 3306, which is the mysql server)
sudo ssh -fNg -L 3307:127.0.0.1:3306 yourvmusername@yourvm.cloudapp.net
//warnings about authenticity will pop up:
yes
//then you’ll see yourvmusername@yourvm.cloudapp.net’s password:
(enter your vm password, NOT your mysql password)
yourvmPassword!
//back to prompt

Go Back to manage.windowsazure.com

Setup End Point on the VM:
(this will be the public port 3307 that we add to the VM, which will then hit the SSH Tunnel we made, and route all traffic to the mySql server)
Click on yourvm in the VM tab
Click Endpoints
Click ADD+ button at the bottom of the screen
Name it anything, I named mine 'MySQL Tunnel'
Use TCP
Public Port 3307
Private Port 3307
Don't check any boxes

DONE WITH SETUP!

Now to Connect to the database from Node or PHP, etc, You Use:
URL: yourvm.cloudapp.net
Port: 3307
User: root
Password: yourSQLpw

(obviously you can create other user accounts and not use root if you want the edit trail)

To Connect to the VM from CLI:
ssh yourvmusername@yourvm.cloudapp.net -o ServerAliveInterval=180
password: yourvmPassword!

Access MySQL Directly from the VM CLI:
mysql -u root -p
password: yourSQLpw

meteor.js: easier default account system files

The account backend in meteor is pretty decent, and is wired up to all the basics, but manipulating the front end is an exercise in frustration, and wiring up the additional features is a headache. The CSS is all wrapped up in compiled files and LASS. So you install one of the packages that removes the styling, but even that makes it a huge pain to change or manipulate the UI. And even then, that UI is tied to some of the basic vanilla behavior and leaves out a lot of the smart and complex features that are available and sometimes necessary.

So instead of making a package that would just be difficult to customize to my needs on projects going forward, I baked all features of the Meteor account system down into 3 files:

customAccounts.html
customAccounts.css
customAccounts.js

By default, all the features are in place, and the UI is styled to match meteor’s home page. As well as being broken into easy to understand templates for all states and use cases…using actual buttons instead of a weird hybrid of hyperlinks and buttons. Every account related feature and function is either wired up in the javascript file, or if it’s a less common feature, then stubbed in with example uses.

Just drop ’em into your project folder, no package installation required.
https://github.com/CHBDev/Complete-Meteor-Account-Pipeline