Dynamically Loading Stylesheets and Scripts in Cordova with Ember JS


We make  bad decisions once in a while and this is what our development team experienced working on an Ember project to be converted to a mobile application through Cordova. “What happened?” you would ask. We made a bad decision of independently coding the version to be converted to a mobile app with that version to be used for web and be converted to a tablet app. And now we are trying to avoid releasing a smartphone-only and tablet-only versions of the application because, let us admit it, it’s not very elegant.

It shouldn’t be a big problem if one design is perfectly responsive to all platforms of course. But that is not the case. And going for that approach while reasonable will already make the project bleed as it will entail some rework. We needed a quick fix and that’s what we tried to work out one lazy afternoon.

We got two independent distributions, one for mobile and one for tablet. We could freely dump their JS and CSS files into the Cordova project’s www folder without worrying about anything. The tricky part is keeping one index.html that will load the right script depending on the device where the application will be installed.

Locking the Screen Orientation

We needed to lock the screen orientation. As what is arguably always ideal, smartphone UI should be in portrait mode while the tablet version in landscape. After some searching, we found this plugin at http://plugins.cordova.io/#/package/net.yoik.cordova.plugins.screenorientation. It’s the only one out of the three we tried that gave us what we wanted. A short tutorial can be found here.

Dynamically Loading Scripts

For seasoned Javascript programmers this should come easy. But for us who mostly do our scripting with jQuery, it required a bit of research. A typical index.html of an Ember project to be converted to a mobile app would look like this.

<!doctype html>
<html>

 <head>
 <meta charset="utf-8">
 <title>Mobile App</title>
 <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, target-densitydpi=medium-dpi">
 <link rel="stylesheet" href="styles/12345.main.css">
 </head>

 <body>
 <script type="text/javascript" src="index.js"></script>
 <script type="text/javascript" src="cordova.js"></script>

 <script src="12345.components.js"></script>
 <script src="12345.templates.js"></script>
 <script src="12345.main.js"></script>

 <script>
 //additional scripts here.
 </script>
 </body>
</html>

The head contains the reference to the compiled CSS and the body contains the reference to compiled components, templates, and main JS files. Obviously we cannot keep it this way. There has to be a way to replace the references on the fly or completely remove all mentioned link an script tags and create them along the way. We did the latter.

We started with a bare index.html.

<!doctype html>
<html>
 <head>
 <meta charset="utf-8">
 <title>Mobile App</title>
 <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, target-densitydpi=medium-dpi">
 </head>

 <body>
 <script type="text/javascript" src="index.js"></script>
 <script type="text/javascript" src="cordova.js"></script>
 <script></script>
 </body>
</html>

Just before we closed the body tag, we inserted the script that shall create the nodes we need. It was written in plain Javascript. Note that the compiled scripts contain the reference to third party scripts so we cannot use jQuery. Another important note is that it should be in index.html; well at least in our case. For some reason we could not get it to work when we moved it to the Cordova project’s app script.

/* Window must be done loading before setting orientation. */
window.addEventListener("load", load);

/**
 * Gets user agent and check if it is mobile.
 * This is a very simple check and must be refined.
 */
var ismobile = (/mobile/i.test(navigator.userAgent.toLowerCase()));

/* Dynamically creates the necessary nodes. */
var style = document.createElement("link");
style.rel = "stylesheet";
style.type = "text/css";

var component = document.createElement("script");
component.type = "text/javascript";
component.async = false; //async is being set to false so that script will not immediately fire.

var templates = document.createElement("script");
templates.type = "text/javascript";
templates.async = false;

var main = document.createElement("script");
main.type = "text/javascript";
main.async = false;

/* Assigns stylesheet and scripts according to device. */
if(ismobile) {
 style.href = "styles/phone.main.css";
 component.src = "scripts/phone.components.js";
 templates.src = "scripts/phone.templates.js";
 main.src = "scripts/phone.main.js";
} else {
 style.href = "styles/tablet.main.css";
 component.src = "scripts/tablet.components.js";
 templates.src = "scripts/tablet.templates.js";
 main.src = "scripts/tablet.main.js";
}

/* Finally appends the elements to head and body. */
document.getElementsByTagName("head")[0].appendChild(style);
document.getElementsByTagName("body")[0].appendChild(component);
document.getElementsByTagName("body")[0].appendChild(templates);
document.getElementsByTagName("body")[0].appendChild(main);

function load() {
 var ismobile = (/mobile/i.test(navigator.userAgent.toLowerCase()));
 if(ismobile) {
 screen.lockOrientation("portrait");
 } else {
 screen.lockOrientation("landscape");
 }
}

We only worked on this for a short time and this can most probably be improved. Feel free to insert your suggestions. -aB

Business Insider: These Guys Raised $7 Million To Create A Calendar App That Thinks For You


As a professional, it’s always about productivity these days. Starting in the industry, I never thought I would have to keep track of how I manage my time. I was just a software developer; at the bottom of it all. If I get my code working, that would be it for the day.

But growing in our chosen careers is inevitable unless we consciously exert effort to stay where we are. A couple of years in, I began looking for ways to keep track of things that need my attention. While smartphones offer a solution, it’s a different story for someone who tries to keep away from technology once  in  a while. Because admit it, even our smartphones take our time. Let’s see if this new app here can do the trick.

These Guys Raised $7 Million To Create A Calendar App That Thinks For You

http://www.businessinsider.com/timeful-calendar-app-2014-8

Logging Pitfall: Let’s just log everything! What could go wrong?


So last week I overheard one of our developers’ discussion with the account manager who happens to be a tech person as well. They were talking about errors encountered by a client’s website written in Python Django. The developer reported that the site just began crashing whenever this or that script starts to write things to the website’s log file and they were expecting that the user under which the site runs has not enough permission to perform logging. It was reasonable since the whole website was moved from one hosting provider to another and it might have been encountering configuration issues. I ignored it. I was preparing for a prototype presentation that afternoon.

That same developer works for my team and even joined me in the presentation. When we got back to the office, she said that she would have to stay a little longer to work on the issue she was discussing with the account manager earlier. That’s when I offered my help. It was Friday afternoon. Although I still got a lot in my task list, I knew that I better start on them the following week.

I asked her to describe to me how the site runs. She said that the site has this main script that runs all the other scripts. The other scripts perform the logging. I asked her to show me a sample of the logs and she showed me what was on her screen. I was expecting a log meant for audit trails but the logs appeared to be those default logs for debugging the website. I could have argued that it should no longer be there in production but I let it go. She was doing maintenance work anyway and debug logs can be helpful. I then asked her if everything was working before. She said yes. I told her it should have nothing to do with permissions then unless the hosting provider messed up with user permissions in the server. She seemed a bit puzzled of what I was trying to point out.

Log files are developers’ best friends. When I was still a student and was developing using Windows’ classic notepad and was not yet acquainted to debugging tools, I referred to logs for errors and “watched” variables. I tended to log everything when frustrated. It was helping me; what could go wrong? I left snippets of code meant to log things when I submitted my works just so I can have a ready reference once something goes wrong. Only when I started working did I realize the problem it could introduce if not done properly.

Programming languages and frameworks are designed to perform things fast. Show a tech person a website that takes a long time to load in the browser for whatever reason be it internet speed, architecture, etc. and somebody will raise one of their eyebrows. This same capability of frameworks to perform processes fast makes a lot of developers forget to properly handle logging.

Concurrency. This can be the number one problem if logging is mishandled. And the annoying thing about it is that you know as a developer that you should be wary about concurrency issues but you missed this one about concurrent log file access because you were treating logging as a small thing. And to make it worse, your website will behave as expected as long as one script finishes logging to the file before another starts writing its own logs; something that is very possible until the website gets large traffic.

I told our developer that Python is a very fast language and that’s probably why the website did okay for years with all the logging that was happening. But now that it’s handling a lot of requests, it’s now encountering concurrent file access issues. For a quick test and patch I suggested that she use different log files and see if the website will still encounter the issue. She reported that it worked. I asked her if it was really necessary to put everything in a single log file but she said she would have to confirm with the client first. I then just told her that if it’s really necessary, she should create a handler that stores all logs in memory and then flushes it in the file after about one to three seconds. There will be a delay but no logs should be lost and there should no more of the IO exceptions that the site is currently encountering. I will find out later. -aB

Featured Image by: ~no-reaction

The UPCAT 2014 Results Out Now


See online results.

Go here for searchable results.

The results of the University of the Philippines College Admission Test (UPCAT) 2014 is now out. Congratulations to all those whose hard labor has been fruitful and have passed one of the most challenging entrance examinations in the country. This is just the beginning of the challenge, we all know that, but for now celebrate for your triumph. I wish you all the best. Have fun on your “toxic” days.

Also, shout out to the new batch of BS Computer Science students from one of your kuyas.

Student Number Name Campus Degree Program
2014-30700 AGIR, KHARL GAEBRIEL AGUILAR MANILA BS COMPUTER SCIENCE
2014-10559 AGUZAR, STEPHANIE ANNE BUTIAL MANILA BS COMPUTER SCIENCE
2014-27736 ALANO, ANGELIKA FAYE SERRANO MANILA BS COMPUTER SCIENCE
2014-25817 ANGELES, SIGFREED JOHN SALCEDO MANILA BS COMPUTER SCIENCE
2014-19252 BARCELONA, DIANE BOLANTE MANILA BS COMPUTER SCIENCE
2014-47783 BUNAG, KENRICK LANCE TAN MANILA BS COMPUTER SCIENCE
2014-50177 CAPARAS, ALETHEA MARI MANILA BS COMPUTER SCIENCE
2014-07077 CHUA, JANE KIMBERLY NIU MANILA BS COMPUTER SCIENCE
2014-49148 CHUATECO, MARIKA DELOS SANTOS MANILA BS COMPUTER SCIENCE
2014-05834 DE JESUS, ANIKA PAULA MATSUO MANILA BS COMPUTER SCIENCE
2014-43376 ESPALLARDO, LLOYD VINCENT ANDARZA MANILA BS COMPUTER SCIENCE
2014-01882 FLORENDO, PRINCESS DANIELLE VALDEZ MANILA BS COMPUTER SCIENCE
2014-55403 GAN, PATRICK LAWRENCE CUA MANILA BS COMPUTER SCIENCE
2014-04108 LAGUDA, REECE ADRIAN CORTES MANILA BS COMPUTER SCIENCE
2014-26004 LIM, JOURDAN RILEY LIM MANILA BS COMPUTER SCIENCE
2014-27438 LIPATA, ANTHONY SOLATORIO MANILA BS COMPUTER SCIENCE
2014-41075 MARPA, DARLENE PSALM GONZALES MANILA BS COMPUTER SCIENCE
2014-00308 MENDOZA, DELWYN PERLAS MANILA BS COMPUTER SCIENCE
2014-41079 MORA, GRACE IRENE ZAMBRANO MANILA BS COMPUTER SCIENCE
2014-40979 OCAMPO, RAFAEL ANGELO SALVADOR MANILA BS COMPUTER SCIENCE
2014-01842 ONGCHAN, HANSSEN PIERRE TAN MANILA BS COMPUTER SCIENCE
2014-32819 ONGCHINKE, JAYSON DELA PENA MANILA BS COMPUTER SCIENCE
2014-61400 PEREZ, JOSHUA ANDREW BELARMINO MANILA BS COMPUTER SCIENCE
2014-56730 QUITO, RAI EARL DON SAN JOSE MANILA BS COMPUTER SCIENCE
2014-05888 REGILME, CHARLENE GRACE SAN JOSE MANILA BS COMPUTER SCIENCE
2014-10019 ROMERO, ROBERT EMMANUEL REYES MANILA BS COMPUTER SCIENCE
2014-60201 SAMONTE, CHERRY ANN PANGANIBAN MANILA BS COMPUTER SCIENCE
2014-66980 SILMARO, BIANCA CAMILLE LAGUE MANILA BS COMPUTER SCIENCE
2014-10868 TABORNAL, NEIL KENNETH CAMACHO MANILA BS COMPUTER SCIENCE
2014-20458 TEJERERO, EDGAR ANTHONY LOYOLA MANILA BS COMPUTER SCIENCE
2014-54778 UY, JOHN BENGEMIN SIH MANILA BS COMPUTER SCIENCE
2014-00731 VILLALUNA, WINFRED LOUIE DELA CRUZ MANILA BS COMPUTER SCIENCE
2014-01740 VIRTUS, ANGEL PATRICIA RUIZ MANILA BS COMPUTER SCIENCE
2014-23703 YAP, RICHELLE SAN MARTIN MANILA BS COMPUTER SCIENCE
2014-02360 ZAMORA, ABIGAIL GALGANA MANILA BS COMPUTER SCIENCE
2014-64917 ZAMUDIO, GABRIEL PORCALLA MANILA BS COMPUTER SCIENCE