A Third-Party Integration in JavaScript

Nowadays, almost any third party application has some kind of backend API where you can interact, or an external JavaScript library that you can load and use, depending on the service.
However, sometimes you have to deal with a third-party integration in javascript, and very limited applications, with a lack of APIs support, and/or documentation.

For instance, a few weeks ago I had to integrate a new shipping method in the checkout process of an eshop. Basically, the user had to go to the carrier website, and select a pick up place. There wasn’t any API where I could retrieve the available places, so the user actually had to interact to the external website.
The available options for the integration were:

  • Redirect the user to the carrier’s page when he selects the specific carrier, and pass a callback URL. Then, once user selects the pick up place, the carrier’s page would redirect back the user, passing all the selected data by GET.
  • Open an iframe when the user selects the carrier as shipping method, passing a callback URL. Then, when the user has chosen the place, the carrier’s page would redirect the parent window to the given callback.

Neither of them were desirable at all, as the first one would require the user to temporarily leave the eshop, and the second one would require to refresh or move to another page, and we have a one-step checkout process.

After discarding the first option, I was wondering how could I retrieve the user’s data from the carrier’s page without refreshing the page, because on the shipping method step, the user had almost finished fulfilling the checkout form, and we needed to preserve all his data.
Firstly, I thought of performing an ajax petition to save the user’s data on session before opening the iframe, and then retrieve them on the page refresh. I didn’t like it at all, though it would probably work, so I discarded it. I had a look at the carrier’s page to see how did they perform the callback redirection. This is the interesting part:

if(parent!=null){
		parent.location=url;
	}else{
		location.href=url;
}

Basically, if the parent window is defined, its location is changed, otherwise, the current window is changed.

Although I don’t like the iframes, I thought that if i put the carrier’s iframe inside another iframe, then, its parent would be my iframe and not the main page, so the checkout page wouldn’t be refreshed and I just would need to retrieve the data.
It seemed a very hackie but “acceptable” solution, so it worth trying. Unfortunately, I realized that chrome and firefox (I didn’t bother to try IE) wouldn’t like it. It seems that it’s not allowed/safe that an iframe attempts to change it’s parent’s location, if it’s an iframe as well. After some research I figured out that I had to think of another way.

I tried to find an alternative way, such as trying to capture iframe’s calls to its parent with javascript, or triggering an event before the window.location was modified, but I had no luck. Eventually, I found that there is an event triggered when the url hash changes (ie: mypage.com/ => mypage.com/#whatever). Maybe I could send the current url as callback concatenated with the character “#”, so when the iframe attempts to change the parent location, it would actually be changing the hash and I would be able to capture the data avoiding refreshing the page.
It seemed a good idea, taking into account the circunstances, so I tried it, but unluckily, as the callback URL is provided by GET, the “#” was being interpreted as hash of the carrier’s url, and the callback variable wasn’t actually containing the “#” character, so the redirection didn’t work as I expected. I mean, the iframe was like this:

<iframe src="carrierspage.com/blablabla?callbackurl=http://mysite.com/checkoutpage#" height="240" width="320"></iframe>

I wanted that the value of callbackurl (on the carrier’s page) was something like “http://mysite.com/checkoutpage#”
But it was actually “http://mysite.com/checkoutpage”, because the “#” was being interpreted as part of the carrier’s page.

After some unsuccessful attempts, I tried url-encoding the character “#”:

<iframe src="carrierspage.com/blablabla?callbackurl=http://mysite.com/checkoutpage%23" height="240" width="320"></iframe>

Voila! It worked smoothly, when the user picked up a place, all the data was being added to the hash of the checkout page, and I just needed to parse the data by JavaScript.

I created a function that would be triggered on the event window.onhashchange, performing the parsing of the url’s hash, clearing the URL, and more uninteresting stuff that is out of the scope of this post.

It was almost finished. I was proud of my -hackie but working- achievement, but then I tested it on IE7. Everything seemed to work, but the onhaschange event.
After some research I discovered that this event is not supported on IE7. Many people suggest an acceptable approach, which consist in constantly checking the location with a timer interval. It’s not so beautiful, but well, it’s IE7.

Finally, I ended up combining both solutions: If the browser is IE7, set the timerinterval and wait for changes on the URL, otherwise wait until the onhaschange event is triggered.

That’s it, I hope it can help you if sometime you get stuck in a similar situation.

Please, remember that any suggestions/improvements/alternatives are more than welcomed.

Alert Dialog

Toast
To interact with the user from the application to show messages sometimes require or ask how you want to happen proceed flow depending on a particular response or choice. For this type have several tools which can display messages popup information or require action.

Some examples are, and you will be using each in the most convenient.

The first option is the Toast messages that are above the screen no matter what application is running, but they have no interaction button, rather serves to show rapid, short and not so important.

Toast toast = Toast.makeText(getApplicationContext(), "Example de Message for Android", Toast.LENGTH_SHORT);
toast.show();

Alert Dialog
The next option is to display a dialog box with the OK button, they are seen only if the Activity is active on the screen but ensures that the user reads it and to press a button to continue the flow.

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Example de Message for Android")
.setTitle("Attention!!")
.setCancelable(false)
.setNeutralButton("Accept",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();

One option that is widely used is to ask the user whether to continue with an activity or not, with the typical buttons yes or no and in some cases with a third option that is often omitted or out. Depending on the option chosen by the user performs different action.

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Do you want to continue with the theme?")
.setTitle("Warning")
.setCancelable(false)
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
})
.setPositiveButton("Continue",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
TransferirDinero();
}
});
AlertDialog alert = builder.create();
alert.show();

List
It could also be a case where we need to show more than one option, type multichoise and responses are not dry. This can display a list of options.

final CharSequence[] items = {"Android OS", "iOS", "Windows Phone", "Meego"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("your preferred OS?");
builder.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
Toast toast = Toast.makeText(getApplicationContext(), "you choise the option: " + items[item] , Toast.LENGTH_SHORT);
toast.show();
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();

This option can be added a radioButtons.

final CharSequence[] items = {"Android OS", "iOS", "Windows Phone", "Meego"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("your preferred OS?");
builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
Toast toast = Toast.makeText(getApplicationContext(), "you choise the option:: " + items[item] , Toast.LENGTH_SHORT);
toast.show();
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();

JavaScript Validation with JsLint

Here I’ll explain how to integrate javascript validation with JsLint in VIM. If you usually have to write some JavaScript code, either using a framework, or just “pure” js code, you should probably use a JS Validator.
Before I started usin JsLint, I used to write the code, save the file, go to the browser, clean the cache (not always but usually), go to an specific page, and eventually test if my code was working.

Sometimes, if have to write just a few lines, I usually do it directly on the firebug or Chrome console, and once I had verified that it works, I copy the code an put it wherever it’s needed on my app.
However, if it’s something bigger, it becomes unhandleable to work on the console, and I rather type the code on the JS files, for the shake of readability.

When I’m coding in PHP, I have a shortcut to directly check syntax errors, which actually helps me a lot. It doesn’t guarantee that the code would work, but at least I know there aren’t syntax errors. One day I was wondering if there is something similar for JavaScript, and after some research, eventually I found it.

It seems that there are several ways to validate JS code, however after trying some of them, I’ve finally choosen JsLint, a static code analyzer for JavaScript source code.

I usually write code using VIM, and debug in NetBeans, so I was looking for some plugin or script that I can easily integrate with VIM. There are many tutorials on the web, however most of them didn’t work as I expected, so I had to combine some of them until I achieved a satisfactory solution.

Okay, enough speech, let’s do it!
I’m using Ubuntu 12 and theese are the steps I followed in order to get it working:
1. You need a command line JS interpreter, and the easiest to install is rhino:

sudo apt-get install rhino

After the installation, you should be able to enter the interpreter just by typing js on your terminal:

Javascript Interpreter

2. You need JsLint and a plugin to integrate it on your favourite IDE (VIM in my case).
Luckly, there is already a JsLint VIM plugin that includes all together, you just have to download the files and put them under the folder ~/.vim/ftplugin. You can find additional help and installation instructions on the link.
Depending on your .vimrc config, you might need to add the following line to enable filetype plugins: filetype plugin on (only if you don’t have it already).

3. After installing the plugin, the validator should be already working:

Javascript Validator

Note that the “wrong” lines are highlighted, and you will see an error description at the bottom once you put the cursor on the line. Each time you save a file with JS extension, the validation will be performed.

4. Now, you have a JS validator integrated on your editor. However, you’ll probably notice that almos every single line will be highlighted, because depending on the JsLint settings, it can be too strict, but you can customize it. In order to do that, create a new file on your home location: ~/.jslintrc and put your custom config. This is the one I’m using:

/*jslint browser: true, regexp: true, nomen: true, sloppy: true*/
/*global jQuery, $, $$ */
/*global _gaq, FB, twttr */
/* vim: set ft=javascript: */

Taken from the JSLint documentation, here is a little explanation of the customizable settings:

anon       true, if the space may be omitted in anonymous function declarations
bitwise    true, if bitwise operators should be allowed
browser    true, if the standard browser globals should be predefined
cap        true, if upper case HTML should be allowed
'continue' true, if the continuation statement should be tolerated
css        true, if CSS workarounds should be tolerated
debug      true, if debugger statements should be allowed
devel      true, if logging should be allowed (console, alert, etc.)
eqeq       true, if == should be allowed
es5        true, if ES5 syntax should be allowed
evil       true, if eval should be allowed
forin      true, if for in statements need not filter
fragment   true, if HTML fragments should be allowed
indent     the indentation factor
maxerr     the maximum number of errors to allow
maxlen     the maximum length of a source line
newcap     true, if constructor names capitalization is ignored
node       true, if Node.js globals should be predefined
nomen      true, if names may have dangling _
on         true, if HTML event handlers should be allowed
passfail   true, if the scan should stop on first error
plusplus   true, if increment/decrement should be allowed
properties true, if all property names must be declared with /*properties*/
regexp     true, if the . should be allowed in regexp literals
rhino      true, if the Rhino environment globals should be predefined
undef      true, if variables can be declared out of order
unparam    true, if unused parameters should be tolerated
sloppy     true, if the 'use strict'; pragma is optional
sub        true, if all forms of subscript notation are tolerated
vars       true, if multiple var statements per function should be allowed
white      true, if sloppy whitespace is tolerated
widget     true  if the Yahoo Widgets globals should be predefined
windows    true, if MS Windows-specific globals should be predefined

Basically, I’ve enabled browser global variables, set the “use strict” as optional, and I set some additional global variables for the external libs that are usually loaded on the pages.
You might disable several validations such as white spaces, multiple var statements and so on, but I think it’s better to get used to this way of coding, as it makes you improve the readability and the quality of the code that you write.

That’s it, now I’m looking for a way to validate JS code inside HTML files, but I haven’t found a solution yet. Do you have any ideas/suggestions?

Password Avoidance and more

I usually have to do many tasks that require to input a password, for instance, connecting by SSH, connecting to a mysql server, or login to several websites in several environments. This is something that has been bothering me for a long time, so I’ve eventually decided to write this post about password avoidance, to show how I usually deal with it.

SSH

Regarding the SSH access, there is a well-known solution that many people use. You can create a public/private key pair to authenticate, instead of typing the password. There are many manuals explaining how to do that, so summarizing, you have to follow this steps:

Generate the pair of keys on your computer :

ssh-keygen -t rsa

Then, you should have your keys on ~/.ssh/id_rsa (private) and ~/.ssh/id_rsa.pub (public).

Copy the public key to the server(s) (entering your password for last time!) and append it to the authorized_keys file:

scp ~/.ssh/id_rsa.pub your_user@your_server:~
ssh your_user@your_server
cat id_rsa.pub >> ~/.ssh/authorized_keys

Update 04/06/2013: Thanks to Christopher for this tip. You can get rid of all the previous commands, and just type the following:

ssh-copy-id -i .ssh/id_rsa.pub your_user@your_server

That’s it, now you should be able to log in to that server without entering a password.

MYSQL

If you usually have to deal with mysql databases, you’d probably find useful this section. You can easily customize your mysql prompt, just by creating/editing the file ~/.my.cnf. This is how mine looks:

[mysql]
user = root
password = my_password
prompt=\u@\h:[\d]>\_

I have set the default user and password, so I don’t have to enter the password when connecting to my localhost (or any host with this credentials). Note that this credentials will be used not only for the mysql command, but also for the mysqldump and mysqlimport.
On the other hand, I’ve added the last line, which I think is quite useful when you are using mysql client. Basically, it will display the prompt in the following format: user@host:[database]. This way, you will always know where are you connected, which user have you used and what database is being used.

Website Credentials

Speaking about website credentials, I’m currently using a browser extension called LastPass. It allows you to create a database of users and passwords URL-related, allowing ou to auto-fulfill and even auto-submit the login form when you load a known URL. On my experience, it’s very useful, as you can use it in both Chrome and Firefox, and you can share some/all credentials with several people (ie. all the development team).

However, it has some drawbacks/possible improvements from my point of view. First of all, there might be more than one user/password for the same URL (ie. admin and user role), and I’ve been unable to specify the priority of the credentials. Sometimes, the stored credentials aren’t valid anymore, and although there is a credential’s suggestion list on the form page, in my case, the list is useless most of times. It would be very nice if the suggestion list showed the credentials of the same domain in first place.

For instance, imagine I have three environments for my site: dev.mysite.com, preprod.mysite.com and www.mysite.com. Then you can assume that if this three sites are related, and the credentials might be exchanged from time to time.

I guess this extension wasn’t designed for developers, but for all kind of users, but that features would be very useful in my opinion.

Finally, this extension has some other cool features as well, like automatically filling registration forms. This feature has been added to Google Chrome lately, so now it’s not as valuable as before, but it’s worth to mention, as it can save you many time of filling the same registration form over and over.

Unix/Linux 

I wanted to talk as well about the passwords in Linux. Each time you have to edit/create a system file, for instance, add a new host to the /etc/hosts file, add a new virtual host on /etc/nginx/sites-available, set writting permissions to a certain folder, and so on, you have to use a sudo command, and therefore, type your password. I can’t tell how much time I’ve lost typing my password over and over. To avoid this there are many possible solutions.

You could just change the permisions/ownership of the file/folder that is bothering you, with sudo chmod 777 FILE / chown username:yourgroup FILE. This is fast and works fine, however, many people would complain because it’s very unsecure, as this files has restricted permissions for security reasons. In any case, if you are the only person who has access to the computer, you can do it, under your own responsability, and you shouldn’t have any problems.

If you wan’t to do it on a more elegant way, you might achieve the same result by customizing your sudoers file. All you have to do is safely open the file /etc/sudoers with your favourite editor by typing: “visudo /etc/sudoers” and append a new line at the bottom. Remember to put the new content under the line/s:

%sudo ALL=(ALL:ALL) ALL
%admin ALL=(ALL:ALL) ALL

Because this rules would override any line written before.

Imagine you want to be able to restart the nginx server, edit the /etc/hosts, poweroff the computer, and execute the chmod command without being ask for the password. You might do it by adding this line:

awesomeuser ALL=NOPASSWD: /etc/init.d/nginx, /usr/bin/gedit /etc/hosts, /sbin/poweroff, /bin/chmod

Note that the changes will not take effect until you open a new terminal.

This way you would avoid entering your password for all these tasks. However, use it under your responsability, and take into account that a misconfiguration might put your computer in risk. For instance, if you put /usr/bin/vi /etc/hosts, take into account that you can execute shell commands from vim, so anybody might type sudo vi /etc/hosts and execute sudo commands from the editor.

Remember that sometimes is better (safer) having to type the password before executing a command, it’s just up to you.

Customizing bashrc, bash aliases, and more – II

On my the previous post, I explained a few tricks that I use in order to move faster through my project. Básically, you can achieve that by customizing bashrc file on your home directory.

Before moving on to a new topic, I’d like to explain some more tips related to my last post. We created a function called “_sitedirs” that was used just as completion of the input of our function. Well, we can take profit of this function and create many more helpful functions.

For instance, if our application logs all the debug and error messages within a project-relative path, we could easily create a function to display them. In my case, all the projects are running on Magento, so by default the logs are being stored on Project/var/log/*.log. Then It’s fairly easy to display the app logs, but I wanted to display the webserver errors as well. I’m using Nginx, and all the project’s configuration are set to save the logs at /var/log/nginx/Proiect.*.log, where Project is exactly the same name of the proyect’s folder. There are two log files for each nginx’s site: the access and errors. I’m only interested on showing the errors, so this is how my function looks:


#Helper to display project log
function logg() {
 tail -f /var/www/dev.$@*/$@/var/log/* /var/log/nginx/dev.$@.*.error.log
}

And in order to use the tab completion, we just need to add the following line:

complete -F _sitedirs -o dirnames logg  

Now, I can type logg, then type any key and/or press [TAB] to complete the name of the project, and that’s it, you can browse trough your project and check out the console to debug it.

There are many other possible usages, like clearing the cache, enabling/disabling maintenance mode, and many more, your only limit is your imagination!

That’s all from now, on my next post I’ll try to explain my aversion to the passwords and how I try to work without having to type a single one (whenever it’s possible).