Skip to Content

Category Archives: Development

Angular.JS controller communication

AngularJS is a Javascript framework made by Google. Over the last few years, its popularity has increased exponentially. Its main features are double data binding, DOM control, form validation and the use of reusable components. Plus, it’s fairly easy to use, which makes AngularJS one of the top choices when looking for a Javascript framework.

When we start working with Angular, we come to this question very quickly: how can we set our controllers to communicate with each other? Which option is the best?

It is typically assumed that in Angular.js there should be only one controller per view. Sometimes, however, we have no choice but to have two controllers within the same page, and they will need to interact with each other.

Given that, I’ll go into some of the typical scenarios and how to handle the communication among controllers for each of them. I hope this is of help for some of you.

Father and Son

This is when we have a controller inside another controller. So let’s say that our markup looks like this:

The problem would be, how can we access the model inside the child controller? If we want to get info already set in the other controller, then we could do something like:

But this only works for reading the value that has been already set. If that value changes, our variable in the controller will not be updated. We could fix that with the following code:

But watch out, an even better solution arrives! AngularJS provides us with some amazing functions that we can take advantage of:

This function broadcasts an event to all children controllers. All the controllers that are listening for the ‘name’ event will get notified. The $broadcast function could be useful if you wanted to send information from the parent controller to a child controller.

On the other hand, if what you wanted was to communicate from a child to its parent, we use this method:

Finally, ‘on’ allows us to define which methods we are listening to. It listens for the ‘name’ event‘ emitted’ or ‘broadcasted’ methods depending on the case.

Communication from parent controller

Here’s an example:

In this example, we are sending a message every time that our variable ‘something’ changes in the parent controller. Use of $watch is not necessary. What we need to keep in mind is that our child’s controllers and listener for the event needs to be defined before broadcasting

Communication from child controller

Here’s some markup example for this situation:

And the code:

As you can see, the parent controller is listening for a ‘new message’ event. While in our child controller we are emitting this event every time we call ‘tellToMyParent’. We are calling that function when we click on the ‘Say it’ button, and it is sending the value of the $scope.message, which, in this case, is the value in the textbox.

Brother controllers

The idea sounds pretty good, right? Unfortunately sometimes this isn’t as easy as it sounds. There will be some situations on which we have brother controllers, and we can’t get them to communicate without the use of a parent controller.

Here’s some sample markup:

We know that there is one $rootScope for the Angular application and that we could take advantage of that. The code inside the controllers is interpreted in the child scope. And, if the property does not exist in the child scope, then Angular will look for the parent scope, ending at $rootScope. You can take advantage of this to help them communicate.

For example:

Great, but there is only one thing left: if we use $rootScope.$on in the controller, this will create duplicate bindings. That is because controllers can get instantiated multiple times (every time the user enters the view, basically). So we need to be careful with that and find a way to avoid adding duplicate listeners, which could affect the application’s performance very drastically.

So, we still have one option left. That is, combining broadcast and services; services only get instantiated once, unlike controllers.

Examples:

First option; simple set and get:

Second option, combination with $broadcast:

So, we have reviewed a few different ways of handling communication between controllers depending on the situation. As you can see, Angular.js is very flexible with this, but that does NOT mean that we should not to try to look for better implementations and follow best practices. What do you think about these options to communicate controllers? Do they seem useful? Have you found better ones? Feel free to share in the comments.

Thanks for reading!

J.

0 10 Continue Reading →

Introducing Planning Poker: manage sprint planning and retros like a pro.

planning-id-01

Intro

Are you happy with the app you use to do feature estimation in your Scrum process? We weren’t either. How about the way you collect feedback after a sprint is done? We’ve got you covered.

Introducing Planning Poker: the tool to manage Scrum pointing sessions AND retrospectives in the same place, under an Open Source license, for free! How sweet is that? In this post, we’ll tell you why we built this app, and what were we looking for (spoiler alert: you will see those expectations fulfilled in our app). Then, we’ll show you how it actually works, on a step-by-step tutorial to master the main features. Finally, we’ll refer to the technical stack and the reasons behind choosing those specific technologies. We want to open up a line of communication to receive comments and suggestions for improvement. In the end, this is Open Source, right?

More specifically, in this post we’ll cover the following topics:

  1. Why we built this app
  2. How it works
    1. Pointing sessions
      • Creating a pointing session
      • Setting point values
      • Joining a pointing session
      • Pointing stories
      • Statistics
      • Leaving a pointing session
    2. Retrospective meetings
      • Creating a session
      • Joining a session
      • Adding entries
      • Editing entries
      • Deleting entries
      • Revealing entries
      • Reviewing entries
      • Leaving a session
  3. The technical stack we used to build it.

 

Let’s get started.

Why did we build this app?

Planning Poker was born out of the need to have a fast, simple, and fun tool for the process of estimating the complexity of a feature. At the same time, we needed something to help us manage retrospective meetings. In Planning Poker, the estimation sessions and the retrospectives are carried out in accordance with the Scrum methodology in a distributed environment. We needed an application that kept these processes simple yet flexible, allowing for the addition of custom values if needed. Since we couldn’t find an application that had this exact set of features, we set forth to do it ourselves.

We also wanted to give something back to the community. During our run as a web dev company, we’ve made use of great open source software, and are grateful to the the people who wrote that software. We thought that if we came up with something worth sharing, we would release it under an open source license and return the favor. It was about time that we built and offered something that could make the lives of Scrum teams easier.

So, how does it actually work?

There are two types of users in our application:

Player: These types of users are only allowed to vote, add and modify all of their entries in retrospective sessions. In this way, moderators can have control of the meetings and lead them without interruptions.

Moderator: This is a role commonly used by Scrum Masters. They are allowed to change the description of the story that is being estimated, and clear values to start a new estimation. In retrospective sessions, they are allowed to reveal entries when users finish entering them so that the team can review entries together.

Creating a pointing session:

In order to start pointing you have to create a session, go to the application’s homepage and:

  1. Enter your username
  2. Select your user type
  3. Click “Start”
  4. Optional: modify the names of the pointing values.
  5. Click “Go”!

 

PointingLogin

Creating new pointing session

Setting point values:

You will notice that you can modify the description (names) for points. We included this functionality to give users the freedom to choose the scale and the names for the corresponding elements that works best for them. However, we have also included the most popular pointing range, the Fibonacci series, which is set as default. So, if you don’t need to change anything on the scale, you can move on to the next step of the process without delay. Finally, we added two more features to allow players to express that they are not sure about the estimation of a certain story, or that they need to take a break.

It is important to note that the application doesn’t store those values in memory. They are refreshed when a new session is created, and the only person who can modify them is the creator of the session.

SettingPointValues

Customize point values and labels view

 Joining a pointing session:

Once a user creates a session, she can invite the rest of the team by sharing the link or session ID with them. All users will be prompted to choose a username and user type.

To join with a link:
  1. Click link.
  2. Fill username and user type in prompt.
  3. Click “OK”.

 

EnterUsername

Enter username modal joining session

To join with a session ID:
  1. Go to our home page.
  2. Fill username.
  3. Enter session ID in the corresponding field.
  4. Choose user type.
  5. Click “Join”.

 

JoinSession

Joining a session with an Id

Pointing:

We provide an input to define the description of the story in order to keep all members on the same page. Since the voting process shouldn’t be affected by teammates influencing each other, your vote is secret and you are not allowed to see other teammates’ votes. Accordingly, they won’t see yours until all players are finished voting.

Pointing

Pointing view

Statistics:

The application displays statistics right after all users have finished voting.  Yo’ll be informed of how many players voted the same value. If there was consensus you’ll be notified as well. Votes can’t be changed afterwards.

Statistics

Pointing Statistics

 

Leaving  a session:

Once your team is finished, you can clear the voting area in order to start pointing a different story. Alternatively, if you have finished your sprint planning, you can just close the browser and the session will be deleted.

Creating a Retrospective session:

This process is very similar to the one for creating a pointing session, except that this time we have to select that we are creating a retrospective session instead.

  1. Enter your username.
  2. Select your user type.
  3. Select retrospective from the session type dropdown menu.
  4. Click “Start”.

 

CreateRetrospective

Create retrospective session as Moderator

 

Joining a retrospective session:

Same as if pointing a session: once you create a session, you can invite the rest of the team by sharing the link or session ID with them. All users will be prompted to choose a username and user type as well.

To join with a link:

  1. Click link.
  2. Fill username and user type in prompt.
  3. Click “OK”

 

To join with a session ID

  1. Go to join session section in the home page.
  2. Fill username and user type in prompt.
  3. Enter session Id.
  4. Click “Join”.

 

Adding entries:

Once you enter a session you can see three columns like these:

Retrospective

Retrospective view

 

  1. Click the “+” button on any column.
  2. Write your entry in the box.
  3. Press Enter.

 

EnterMoreOf

More of column in add entry mode

 

WritingMoreOf

Writing an entry for More of column

 

AddedMoreOf

Added entry in More of Column

 

Editing Entries:

Once you add an entry you are allowed to edit it by clicking on the pencil icon.

  1. Click edit icon.
  2. Modify entry.
  3. Click “OK”.

 

 

EditingEntry

Editing an entry modal

 

Deleting Entries:

You are allowed to delete your entries too, just on the trash icon next to the entry.

RetrospectiveEntry

Revealing entries:

Only moderators are allowed to reveal entries, this will show the content of the entries to all users. You can do it by clicking on the “Reveal” button.

Reviewing entries:
ReviewEntry

Preview entry in review mode

 

Once you reveal entries you will be allowed to click on them. That will open a pop up with the text of the entry so you can read the complete entry. There’s an option to mark them as ready or go to the next/previous button.

MarkedAsRead

More of entry marked as read

 

If you are a moderator, you have the option of showing where you are with the rest of the users in the session. With that, you can make sure that all users are looking at the same thing, reading the same entry.

Show for others option

Show for others option

 

Leaving  a session:

This works exactly the same as pointing sessions. When you finish your retrospective meeting, you can just close the browser and the session will be deleted.

How is it built?

We chose Node.js as the main backend platform for this project. We did this because of its “Event Loop” feature and because it does asynchronous operations, which makes our I/O operations fast. But that’s not all, it also features socket support. As you probably know, websockets are two-way communications between the server and the client via TCP instead of HTTP. This means that you can create powerful real-time applications that can push changes immediately. In our case, this came in handy when displaying user votes.

Using Node.js helped us reduce the number of issues that commonly occur when working with multiple languages. Since we had JavaScript already running on the server and the browser, it just made our lives easier. We also used Angular.js. We chose it mostly because of the ‘data-binding’ benefit. Since we were building an application with real-time output, we needed to keep the UI updated, and Angular.js is perfect for that. We’ve been working with this framework for a while, and it makes our development process faster. Plus:

  • It’s maintained by a very friendly and highly-skilled community.
  • It allows for the extension of HTML.
  • It allows for dependency injection.

 

We needed to chose a Javascript library to handle websockets, so we went for Socket.io. We did this for these reasons:

  • It handles browser inconsistencies and varying support levels.
  • It includes additional features like rooms, which allows for work in different teams/rooms/sessions/channels.
  • We think it’s the most reliable real-time engine for Node.js so far.
  • It’s easy to use.

 

And finally, we included Express.js too. We know there are a lot of new frameworks for Node.js out there, but since reliability is of the highest priorities for us, we had to go for Express.js. It has been available for a couple years now and its community and creators are very active. Besides that, this framework is simple and very flexible, and allowed for scalability.

We hope that you found this post interesting. If you have any questions or comments feel free to leave them on the comments section below. Here’s the link to the project on Github. Have a suggestion or found a bug? Send a pull request and we’ll be happy to take a look. We at TangoSource are constantly looking for new and interesting projects that empower our clients and keep the end-user happy. Have something in mind? Send us an email at info@tangosource.com, we’d love to talk 🙂

Thanks for reading!

J.

6 5 Continue Reading →

A Tmux crash course: tips and tweaks.

~ Intro

If you are one of those devs who uses the terminal a lot and ends up with way too many tabs open, or practices pair programming, then this post is for you. During the last months, I’ve started using Tmux a lot. Since I’ve found it to be very useful, I thought I would write a post where I share a few recommendations and pro-tips. I’ll show you what Tmux is and how to use it in combination with Vim to make a more effective and elegant use of the Terminal.

So, this is what we’ll cover:

  1. Tmux basics.
  2. The best of Tmux
    1. Windows
    2. Panes
    3. Sessions
    4. Fast text navigation and copying
    5. And a very neat pair programming feature
  3. Tweaks to improve Vim integration.
    1. Colorscheme background
    2. Static cursor shape
    3. Indentation at pasting
  4. A few extras to enhance the Tmux experience.
    1. Tmuxinator for session automation.
    2. Changing your color of your Tmux bar.

 

An important thing to bear in mind, this is the tool stack I had installed while writing this post, I tested what I say here with these versions:

  • Tmux 1.9a
  • Vim 7.4
  • iTerm 2.1
  • Mac OS (Mavericks and Yosemite)

 

Let’s start!

 

~ The Basics

What is Tmux?

Tmux is a tool that allows running multiple terminal sessions through a single terminal window. It allows you to have terminal sessions running in the background and attach and detach from them as needed, which is very useful. Later on, we will see how to make the most out of that feature.

Here’s a screenshot of a Tmux session:

What you see in the image:

– Left: Vim

– Right: a system’s shell

– Bottom-left: the Tmux session name (“pomodoro-app”)

– Bottom-middle: the current Tmux windows (“app log”, “editor” and “shell”)

– Bottom-right: the current date

How to install Tmux?

In Mac OS:
  1. Install Homebrew

Here’s more info.

  1. Install Tmux:

In Ubuntu:

Run this on the terminal:

The Tmux prefix

In order to isolate its own keyboard shortcuts from other shortcuts, Tmux provides a shortcut prefix. When you want to trigger a Tmux shortcut you will press the Tmux prefix and then the Tmux shortcut key. The prefix that Tmux uses by default is Ctrl-b (“Ctrl” key in combination with the “b” key). For instance, let’s say you want to trigger the shortcut that lists the current Tmux sessions, which is the *s* key. Here is what you will need to do:

  1. Press Ctrl-b keys (Tmux prefix)
  2. Release Ctrl-b keys
  3. Press the s key

 

A few recommendations:

  1. If you have not already mapped the *ctrl* key to the *caps-lock* key and vice-versa I suggest you do it.

 

Calling ctrl from the caps-lock key is very practical. This is because when coding you need to call ctrl very frequently. Moreover, it is a lot easier/quicker given the caps-lock key aligns with the default position of your fingers in the keyboard.

 

  1.  I recommend changing the Tmux prefix to Ctrl-a . Once the  *Ctrl* key has been set to the *caps-lock* key, it gets a lot easier/quicker to call Ctrl-a instead of Ctrl-b, because the new prefix keys are very close to each other on the keyboard.

 

Here is what you need to add in your ~/.tmux.conf file to change the prefix to Ctrl-a:

 The config file

*~/.tmux.conf* is a file that Tmux reads every time a new session opens. It’s where the customizations for Tmux need to be placed. Suggestion: in the case that you need (and chances are you will) to apply a new change made to the without opening a new session, you can add the following line to the ~/.tmux.conf file:

This way, once you have added a new change to the *~/.tmux.conf* file, just press ctrl-b R to reload your configuration without having to open a new Tmux session.

 

~ The best of Tmux

Quick note: the screenshot shown here may differ slightly from what you see by default when you install Tmux. This is because I modified the status bar. If you want to do the same follow the steps on the “Pimp your Tmux bar” section of this post.

Panes

I like the idea of dividing the screen vertically, so that on one side of the screen I have Vim and on the other side I have the output of my code. I could even have another console if I wanted to. Here’s how Tmux makes it happen:

What you see in the image:

– Left side: Vim (at the top: a Ruby class file, at the bottom: a test file for the Ruby class).

– Right side: a bash session.

A vertical *pane* is easy to create. Once you have launched a new Tmux session just press “Ctrl-b %” and a new vertical pane will appear. Also, if what you need is a horizontal division then press “Ctrl-b “”. Navigating through Tmux panes is easy, just press the Tmux prefix and then any of the direction arrows depending on which pane you want to go.

 Windows

In Tmux, a window is a container for one or more panes. Tmux windows allow you to arrange multiple panes inside windows depending on what you need. For instance, in my case I usually have one window called “server” for running the app’s server (where I can see the log), another window called “editor” (where I do the coding). One pane for Vim and another for running the code tests. And another window called “shell”, which is a bash shell where I can run system commands. Tmux windows are useful since they allow users to allocate panes inside of them, to see more about each pane by going to the window that contains it. This is an efficient use of the available screen space.

The list of existent windows in a Tmux session displays at the bottom of the screen. Here is an example of how Tmux displays (by default) the list of windows created. In this case, there are three windows: “server”, “editor” and “shell”):

image3

 

In order to create a new window you need to press “Ctrl-b c”. To navigate through windows press Ctrl-b followed by the index number of the window you want to go. The index number displays next to the name.

Sessions

A Tmux session can contain multiple windows. Sessions are a neat feature; I can create a Tmux session that is exclusive to a particular project. To create a new session just run the following command on your terminal:

If I need to work on a different project I will just create a new session for that. Although the focus will be on the new session, the original session will remain alive. This allows me to get back to it later, and continue where I left off. To create a new session press Ctrl-b : and then enter the following command:

Tmux sessions remain alive until you restart your machine or you explicitly kill the session. As long as you don’t restart your machine, you can jump from a project’s session to another as you need it.

 

Navigation through Tmux sessions

To get a list of the existing sessions, press Ctrl-b s. Here is an example of what Tmux will show you:

image4

Each session listed has an ID number, starting from zero. In order to go to that session type the session’s ID number in your keyboard. In the case that you are not in Tmux but you have one or more sessions running just use:

This command will take you back to your Tmux sessions.

Fast text navigation and copying

I always disliked the fact that to copy content from iTerm2 quickly you need to use the keyboard plus the mouse. I think that there should be a quicker way to do it without having to use the mouse. Fortunately, Tmux allows for that, since it is run from the command line, where the use of the mouse is not allowed.

Navigate text

Tmux allows for text navigation in a way that is very similar to Vim. You know, where the k key goes one line up, w moves one word forwards, and so on. Yet you can increase Tmux’s similarity with Vim by telling it to use the *vi* mode. Here is what you need to add in your *~/.tmux.conf* file to accomplish this:

Send copied text to System’s clipboard

By default, when you copy text from Tmux, the text is only available to be pasted inside that same Tmux session. In order to make that text available to be pasted anywhere, you have to tell Tmux to copy to system’s clipboard. Here’s how to do it:

  1. Install retach-to-user-namespace, this is very easy with brew, just run the following command:

  1. Update ~/.tmux.conf file

Select and copy text

Now that the *vi* mode is set and *rettach-to-user-namespace* installed, let’s see how to copy text from a Tmux session. Let’s say you’ve run the *ifconfig* command because you wanted to copy your ip address. Now, follow these steps to copy that text:

  1. Enter copy mode: ctrl-b [. You’ll see a short highlighted text appear at the top right of the screen as in the following image (“*[0/0]*”).

 

image5

  1. Start moving across the text as you would do in Vim: with j, k, l, h, etc..
  2. Once you get to the text you want to copy press the spacebar and start selecting text (exactly as you would do it in Vim).
  3. Once text is selected press the enter key

 

Now that you have copied your IP address, paste it wherever you want.

Make text copying even more Vim-like

You can use *v* key to select text and *y* to copy it, just add the following to your *~/.tmux.conf* file:

Effective pair programming

You can share the address of a Tmux session with someone else, and that person can connect to the session via *SSH*. Since the connection runs over *SSH*, it will be very lightweight. For the user connecting to the remote Tmux session, it will feel as if the session is running locally, providing the internet connection is fast enough.

Tmux with Tmate

Tmate is a tool that makes it very easy to create a Tmux session and share it with someone else over the internet. To share a new Tmux session using Tmate these are the steps you have to follow:

  1. Install Homebrew:

  1. Install Tmate

  1. Launch a new session with Tmate:

  1. Copy the SSH URL given by Tmate on the Tmux session. An example is showed in the following image (message at the bottom: “*[tmate] Remote session: ssh …*”):

 

image6

  1. Ask the other person to access via *SSH* using the URL you just copied.

 

Now that you know how to make good use of Tmux’s pair programming feature, you can further improve the interactivity of your session by doing a voice call via your preferred provider.

 

~ Tweaks for Vim integration

Colorscheme background

When I first opened Vim through Tmux I found the colors weren’t being correctly applied. The background color was being displayed only where characters appeared. Here is an example:

image7

This issue is due to Vim’s need of setting a different term parameter when ran through Tmux. To set the right term parameter just add the following lines to your *~/.vimrc* file:

After updating the ~/.vimrc file, the color scheme is displayed correctly:

image8

Static cursor shape

By default when Vim is run through Tmux, the cursor shape is always the same regardless of the current Vim mode (insert, visual, etc). This makes it hard to identify the current Vim mode. To fix this, you need Tmux to tell iTerm to update the cursor shape. You can do it by adding the following to your ~/.vimrc file:

*Thanks to Andy Fowler who originally shared this tip.*

Indentation at pasting

Sometimes, when pasting text into Vim the indentation of the text is changed, which is a problem when you paste a large amount of text. This issue can be prevented by executing :set nopaste before pasting. However, there is a better way to do this. By adding the following to your ~/.vimrc file, Vim will automatically prevent auto-indenting the text when pasting:

*Thanks to Marcin Kulik who originally shared this tip.*

 

~ Nice extras

Tmuxinator (automate sessions for your projects)

Let’s say you start coding for application A and you always create a Tmux session with three windows for that: “servers”, “editor” (for the project’s code) and “shell” (to run system commands). At certain point of the day you need to temporarily switch to application B, and you will create a Tmux session with the same windows arrangement you had for application A, with a few slight differences (such as the directory and some commands). With Tmuxinator, you can declare the configuration for each Tmux session and then create them with a single command! Pretty sweet.

Tmuxinator is a gem that allows you to automate the creation of Tmux sessions. It is done specifying the details of the sessions in the configuration files and then creating the sessions with a command.

Let’s see how to install Tmuxinator and how to add the configuration to start a project session. Install the Tmuxinator gem by running the following command:

Now that Tmuxinator is installed you can run the tmuxinator or mux commands from the system’s shell. Let’s create the configuration file for your first application as described above (three windows: “servers”, “editor” and “shell”), tell Tmuxinator to create and open the config file for this project:

At this point the file ~/.tmuxinator/project_a.yml should have been automatically opened. In order to accomplish what is needed for project A you need to update the content of project_a.yml to:

Once you have added the configuration to the Yaml file for project A, just run the following command to start the Tmux session:

Or, if you prefer, use the Tmuxinator alias:

There you have it. Now, in order to start coding for project A just run the Tmuxinator command.

*Find the official documentation in the Tmuxinator repo.

Pimp your Tmux bar

By default, the Tmux bar looks like the following (green bar at the bottom of the image):

image9

You can change its appearance if you want. In my case I like something cleaner as in:

image10

In order to accomplish it, I use the following settings in my ~/.tmux.conf file:

~ Conclusion

In summary, we revised basic functionality and the most useful features Tmux offers. We also reviewed a few tweaks and extras. What are your impressions about Tmux so far? Are there any other features/tweaks that you have found useful? Let us know in the comments section below.

Thanks for reading!

TN.

13 28 Continue Reading →

HTML5 Canvas: playing with shapes and images.

The World Wide Web Consortium (WWC) introduced Canvas with HTML5 last year. We think it’s a pretty interesting drawing tool. So, we decided to experiment with it and share our findings in the form of a short tutorial in this blog post. We’ll cover the basics and mention a couple of recommendations for deeper learning.

To start understanding Canvas, think of it as an area on your page where you can draw and render graphs. It’s user together with Javascript, taking advantage of its properties and methods. Its purpose is to be a container for graphics, as it has no drawing abilities on its own. It may seem like a simple element, however, it can be used for complex tasks, like creating 2D animations. You can see examples of what Canvas can do here. Most modern browsers support Canvas, such as Chrome, Firefox, Safari, Opera, and Internet Explorer 8 and later.

Getting Started

In order to start drawing we need to add the Canvas element to our page, we’ll do it with this code:

<Canvas id="Canvas" width="800" height="480"> Your browser does not support HTML5 Canvas</Canvas>

As you may notice, we defined a width and height for this element. If you don’t define the size, it will use the default values, which are 300x150px. Inside the Canvas tag, you can write a message to be displayed if the browser does not support it.

1

The Canvas element is displayed in light blue.

Once we have added our Canvas element, we’ll use Javascript to get the “context”. You can insert Javascript code in the HTML header, a script block or even in another file. The code should look like the following:

var d_Canvas = document.getElementById('Canvas');
var context = d_Canvas.getContext('2d');

And now we are ready to draw!!!

We’ll start with the basic forms and shapes:

Text

In order to show text in our element, we need to take care of three things: font, fillStyle, and fillText. More specifically, this is what you should do:

– Define size and font type in the “context.font” property.
– Define text color in the “fillStyle” property.
– Use the “fillText” function as in the example below. The first parameter is for the text to show, and the next two are the X and Y axes, respectively.

context.font = "30px Arial";
context.fillStyle="#000";
context.fillText("Hello, World! This is a text", 20, 100);

2

Canvas now displays a gray color.

Square

To draw a square or a rectangle we use “fillRect”. Once again, we are defining the color of our square with the “fillStyle” function. When using “fillRect”, we have to include the following parameters: (positionX, positionY, width, height).

Example:

context.fillStyle = 'red';
context.fillRect (175, 75, 50, 50);

3

And this is what we get from Canvas.

Circle

To draw a circle we use “beginPath” first and then “arc”. First draw the outline and then call the “fill” function. The code should look like this:

context.beginPath();
context.fillStyle = 'green';
context.arc(200, 100, 50, 0, Math.PI * 2);
context.fill();

5

And this is the result.

The “arc()” function takes the following parameters: (x, y, radius, starting angle, ending angle, anticlockwise). As you may notice, in this example we didn’t use the anticlockwise parameter, as it is optional, and it wouldn’t have changed the result.

If you’re wondering about the meaning of those parameters: here’s what they mean]:

Starting angle: angle in radians to start drawing the outline (0 will be at the three o’clock position)

Ending angle: the ending angle in radians.

CounterClockWise: boolean value that draws anticlockwise when true, and clockwise when false.

Gradients

We can fill a shape with a color gradient, which means that a filling can start using one color and end with another. To do this in Canvas, we create a gradient using the “createRadialGradient” method, in which we specify two circles. The first circle is where the color is going to begin changing, and the second one tells Canvas where the color gradient is going to end. To declare every circle, we pass the X and Y coordinates of the circle’s center and radius to the “arc” function. Take note, the gradient could use other fillings if needed.

var grd = context.createRadialGradient(190, 60, 15, 190, 80, 50); //x1, y1, radius1, x2, y2, radius2.

Once we have declared the reach of the gradient, the next step is to set the gradient’s colors. We do this by using the “addColorStop” method, which requires two parameters. The first one is the “stop” or the point in which the color will begin. Stops go from 0 to 1, so make sure you distribute your colors between those numbers. The second parameter is the color we want to paint on that stop.

grd.addColorStop(0, '#F00');
grd.addColorStop(.2, '#FF0');
grd.addColorStop(.4, '#0F0');
grd.addColorStop(.6, '#0FF');
grd.addColorStop(1, '#00F');

To assign our new gradient to our shape we use the “fillStyle” method to tell the context that its filling is going to be the gradient we just built. Finally, we invoke the “fill” method to tell the context to fill the shape with the gradient.

Example:

context.beginPath();
context.arc(200, 100, 35, 0, Math.PI * 2); // A regular circle figure.
context.fillStyle = grd
context.fill();

6

And you’ll get this result.

Ellipse

For ellipses, use the “ellipse()” function, which requires the following parameters: (x, y, radiusX, radiusY, rotation, start angle, ending angle, anticlockwise). The rotation parameter indicates how much will the ellipse turn on the axis. In radians, as usual.

Here’s an example:

context.beginPath();
context.ellipse(200, 100, 50, 20, 0, 0, Math.PI*2);
context.stroke();

7

And this is how it would look.

Line

We use the “beginPath” function to declare that we are about to draw a new line path. Next, we use the “moveTo” function to state the starting position (imagine that you are moving a cursor). And then we use “lineTo” to draw a straight line from the starting position to the ending position. And finally, we need to call stroke() to “paint” through the covered path.

Example:

context.beginPath();
context.moveTo(75, 50);
context.lineTo(350, 180);
context.stroke();

8

The result.

A pretty cool thing we can do with Canvas is to render an image. We can draw an image directly from an existing image element within the HTML document or use an external picture.

In order to use an internal image element, we have to include the image element with a specific ID inside the document.

<code><img id=”dog” src=”http://3.bp.blogspot.com/-lCei4CIR7J8/UOXuPWztz5I/AAAAAAAAAAw/iNkkVQzUV88/s1600/cute_little_dog_wallpaper-1024×1024.jpg” alt=”Dog” width=”100″ height=”110″></code>

Then, we get the image element by its ID using Javascript, and use the “drawImage” method to render the image in the canvas:

var img = document.getElementById("dog");
context.drawImage(img, 110, 0, 180, 200);

In this case, the “drawImage” method has the image element as its first parameter, then the X and Y coordinates, and finally the width and height of the image in the canvas. Also, you can see that the original HTML element is visible, so it is recommended to hide it.

9

This is the result.

But, if we want to use a picture that is outside of our HTML document, then we have to create an object of the “Image” type first. Then we can assign it an external source path. We invoke the drawing method on the “onload” event of the image so the picture can draw itself the moment it’s fully loaded. If we don’t do this, the drawing method may fail because the picture won’t load when the drawing method is invoked.

var image = new Image();
image.src = "http://www.mycatspace.com/wp-content/uploads/2013/08/adopting-a-cat.jpg";
image.onload = function(){
context.drawImage(image, 100, 0, 200, 200);
};

10

This is what you get with the code above.

With Canvas, there are no limits to your creativity, just let it flow…

If you want to avoid repetitive tasks, there are some frameworks that can help you speed up your work. Some of them specialize in picture handling and others in making charts or creating filters and effects. Take a look at FabricJS, ChartJS and PaperJS if you want to explore these possibilities.

Another great feature of Canvas is that you can create graphic content in real time, and even respond to user events. A couple of final tips: remember that in order to start/reset a path you need to call the “BeginPath()” function. Here’s a pretty useful cheat sheet with frequently-needed code, and a live example you can use for experimentation purposes.

We hope you found this post useful! Let us know what you think in the comments section.

Thanks for reading!

J.

0 10 Continue Reading →

Don’t let working remotely ruins your performance

Certainly, the concept of ‘remote work’ sounds very tempting…

Ill

(Photo credit: Jan Kaláb)

… but don’t let that fool you! Working remotely is a double-edged sword.

I have found three main areas you need to take care of if you want to stay productive while working remotely: discipline, communication, and time zones. Keep reading to see why I am saying this, plus some tips that will prevent you from performing poorly. And who knows, perhaps you’ll end up having a better performance working remotely than if working onsite.

Discipline

I remember the first time I worked remotely, it felt awesome! I could start or pause work at any time I wanted. And that feeling of freedom, of being able to go to the kitchen and grab some food, watch some TV if I got bored… it was great. I used to wake up at 9:00am, have breakfast, take a shower, and then start work at 10:00am. At this point I was running an hour late, if we compare it with a typical office schedule.

It didn’t take long before I found myself working the whole day. Starting at 10:00am, making frequent breaks, plus doing all the chores and errands a normal person in his twenties has to do. The result: I ended my work days at 12:00am… I had turned into a slave of the freedom that I had.

The solution

You need to take remote work as seriously as if you were working onsite. Remember, with so much freedom it might not seem like it is the same, but you still have have a job to do!

Obviously, taking breaks once in a while does not hurt, but I recommend you avoid granting yourself too much freedom until you have mastered your procrastinating nature. It’s possible to tell if your impulses are under control after a couple of months of working on it, tracking how successful you have become at achieving your goals. And yes, you read right, it takes months. It has been proved that it takes over 2 months of daily practice to develop and establish a new habit.

If it is very hard for you to be disciplined, there are some tools available out there that could help you keep focused on work. A very popular (and effective) one is the pomodoro technique. This time-management method can help you improve your focus and mental agility. Pomodoro promotes work intervals that last 25 minutes, and are alternated with 5-minute breaks, thus increasing your productivity. I have tried it myself and it works, it structures your work day in a way that makes you spend your time more efficiently.Try it out yourself and see if it brings any positive changes to your productivity.

Communication

When I started working remotely I was in charge of a team of 3 people. As you can imagine, not only was my own performance compromised, but also that of my team and project’s. Unread emails and messages were something I had to deal with every day; slowly but surely this was something that was affecting our work deliveries.

The solution

Remember, when you work remotely, you aren’t really alone. You have co-workers, clients, supervisors and other people you work with. Because of this, it is very important to share your status frequently. You can decide on different strategies with your teammates. These are some I personally prefer:

1. Email at the beginning and at the end of the day. I recommend this specially to improve communication with your client. Generally, they are very busy during the day because they have very tight schedules. A good practice I like keeping is sharing my work plan for the day with the client, using the following Scrum-based format:

  • What I accomplished since yesterday:
    • goal 1
    • goal 2
    • goal n
  • What I’m planning to accomplish today:
    • goal 1
    • goal 2
    • goal n
  • Impediments:
    • list the stuff that prevented you from achieving a goal

 

2. Use text messengers appropriately. Use them concisely and only when communicating important stuff to your teammates, you don’t want to interrupt them frequently as you don’t want to be interrupted often either. Here are some examples of things worth communicating and how to do it briefly:

  • ‘A bug appeared in production…’,
  • ‘I finished the feature…’
  • ‘I would like to know the status of…’
  • Or simply ‘I am leaving!’, so everyone is aware you won’t be available from that moment on.

 

3. Keep project management tools updated. Some PM tools allow the addition of comments inside stories (also known as tickets). I recommend you to keep your stories updated by adding a comment with an status whenever any of the following happens:

  • You hit a milestone while building a feature.
  • You have made progress solving a bug.
  • You are going to perform a chore.
  • You are stuck.

 

This way, the client and your teammates know what’s the progress on that story. You will help others to determine if the committed work is in risk of not being delivered, and you can receive help to speed up your work.

Beware of different time zones

This is perhaps the least harmful of the three, because it does not affect your work directly, but it can be a rock in the shoe. I didn’t know this was going to be a constant pain until I started working remotely. I had to deal with 3 different time zones: our customer was on PST, my co-workers on CST, and I was on EST. I was 3 hours ahead of our customer and 1 from my co-workers, and this brought communication issues. When any of them tried to contact me it was very likely that I had already finished my work day.

The solution

Be sensible when arranging meetings, inform others the time when you usually have lunch. Let them know at least one week in advance if you are going to take days off (including those you take for religious reasons, if that’s your case). It took me about 4 weeks to get used to all time zones and to adjust my personal schedule, sometimes having to move my lunch time an hour earlier or later, but at the end it was worth it.

Other good practices

Here at TangoSource we are proud of our remote work practices. We summarized best practices for remote work on our playbook so that anyone can work remotely effectively. Here are a couple of examples:

  1. Create a daily routine list. This list contains recurring action items that you will be checking at the beginning, during, and at the end of the day. An example of a daily routine is: checking and answering emails at the beginning of the day, check messenger apps during the day, and sharing your status at the end of the day.
  2. Create a weekly routine list. This list contains all action items that you will need to take care of during the week. Example: meetings, days off, deployments to servers, etc. Having this routine will help you to have a well-organized schedule.

The conclusion

It took me four to five months to master the three areas mentioned above. If you’re struggling to deliver results while working remotely, or if you’ve never done it and are afraid to try, well, now you know what to do. Put these ideas in practice, don’t give up, and soon you’ll be ready to work from the Caribbean!

Are you interested in learning more about TangoSource and having us as part of your development team? Shoot us an email! We would absolutely love to hear from you! 🙂

by Marco Gallardo: Email / Github

2 8 Continue Reading →

Learning Scrum is easy, following it not so much.

A couple months ago I heard one of our team members say that “Scrum wastes a lot of time on meetings” and that “most of them are not even necessary”. If we look at this idea from the developer’s point of view it’s understandable, being part of a Scrum ceremony, listening to everyone when sometimes the topic has nothing to do with her role or feature, might seem boring. But did you know that a single team member can screw up an entire project (even without noticing) by not following a scrum process correctly?

According to the methodology, there are some events in which the developer has to participate, but there are other equally important tasks that the developer needs to do to help with the larger development process. In this post, I’d like to do a quick review of the five ceremonies of Scrum to help us reconsider their value.  So, first things first, let’s begin with…

Definition of Done

Contributing to the creation of the definition of done is important for a successful development process, since having an unclear definition might cause misunderstandings, eg: miscalculating the remaining work for each feature, incorrectly estimating the features at the beginning of the sprint, or not being clear on if a story should be delivered within a sprint or not.

The team shouldn’t make the mistake of leaving a single person (usually the Scrum Master) to write down the definition of done. Making a good one is a shared responsibility between all the team members and the Product Owner.

To accomplish this step all the team members should share their opinion about what should or shouldn’t be part of the process of delivering a feature based on their experience and their team dynamics. For instance, if their experience says that they should do TDD or that the team works better with small pairing sessions instead of pull requests for code review, they have to share their thoughts to make a Definition of Done that fits their specific needs.

On one occasion, on the last day of a sprint, one of the team members finished a feature he had been working throughout the sprint. He could not deploy it to the staging server since on that day there was nobody that could review his code. During the daily stand up he didn’t report it as an impediment because, from his perspective, the development process had ended when the coding phase had finished. At the end of the day, when the Product Owner checked the work from a local computer, and in spite of the fact that the feature was technically working, he considered it to be useless because he wasn’t able to show it to any stakeholder for testing. When I was asked for my opinion (and observing it from an external point of view) it was more than obvious that there was a failure in the definition of Done. For the Product Owner, it was required that a feature was on staging to marked as complete. Unfortunately the development team never had it clear.

After talking about the situation, the team stipulated in the definition of done that in the case that a code review couldn’t be performed, the developer would have to do a code refactor by himself. But for a feature to be considered as completed, it must have been deployed to staging.

After all, there is no “correct” or “incorrect” definition of done, but there is a correct way to go about defining it. Collaboration is necessary.

Backlog Grooming Meeting

In this ceremony, the developer will clarify all the stories in the backlog and should accept or reject them as a part of the next sprint.

Backlog

  • There can be no trace of doubt afterwards: The developer has to remember that the stories presented in the backlog grooming are items that she will be working on sooner or later. It’s very important to clear all doubts and vague concepts no matter what, and be aware that there are no stupid questions if they help to fully understand the stories.
  • Technical challenges: When the developer is asking questions, it is also important to think about their implementation. For instance, the knowledge that she has about certain tools or programming languages. Sometimes, there are technical limitations that won’t allow for the development of a story as it was designed initially.
  • Take a look at the current code base: It might happen that the Product Owner asks for a feature that sounds easy to implement, but when the code is analyzed the realization comes that it will be much more complicated than originally thought, because of the current code base. If a development team keeps the big picture in mind, they will have a better idea of how to implement each feature and be able to ask smart questions based on that.  It is easy to fall for this when new team members enter a project, or when the team starts working on a part of the application that hasn’t been touched for a while.
  • The team has the control: The team needs to remember that they can reject the stories if they are not well described or if they can’t be developed with as requested. Even when the story is simple to the naked eye, it’s always better to write at least one acceptance criteria.

Sprint Planning Meeting

As we’ve already seen, it’s important to answer any questions that the team may have about the stories. Once every question has been resolved, the team will proceed to estimate the stories. Regardless of the estimation method, there are some points that every team has to consider for a proper estimation.

  • Make conscious estimations: It is always a headache for the development team to make a precise estimation for the stories, however it is important to try our best to avoid over or underestimations. That’s because, down the road, the team will use those stories for reference purposes, and if they are not even close to reality, future estimations will be affected.
  • Keep in mind the Definition of Done: once the team is doing the sprint commitment, it’s easy to forget about the definition of done. It is essential to always keep in mind the whole set of steps that make up for it to avoid over-commitments.
  • Looking at the history: It is necessary to consider previous sprints as a reference for the incoming commitment.  A useful rule,  do not make a commitment of more than what has been delivered on the previous 3 sprints.

 

Daily Standup

The daily standup meeting might be the most important ceremony in Scrum since it’s all about keeping the team coordinated between them. This is the moment when the team can share to each other about the progress made, impediments, achievements or any relevant situation that the team needs to be aware of.

  • Believe that somebody else can help: it is very common that one of the team members can’t realize that he has a blocker. This is where the Scrum Master comes to the rescue. It is important to be humble here and remember that the Scrum master is the one that is overseeing the process and he can easily discover when somebody needs help.
  • One step at a time: another good practice here is to use this event as a “commitments ceremony” to be able to determine if a story will require support from the Scrum Master. If the team members make small commitments on a daily basis, it is easier to remain focused on the sprint goal.

 

Sprint Review

At Tangosource, instead of having a meeting for this at the end of each sprint, we have daily reviews done by the Product Owner.

Sprint-Review

We have a golden rule when testing and reviewing: “Go by the acceptance criteria”. It sounds obvious, but it’s easy to forget sometimes. Before delivering a story, we make sure that we have double checked that every criteria has passed. By following this golden rule, the development team ensures that the story is achieving the goals that the Product Owner wanted, lessening the possibility of having a rejected story.

Sprint Retrospective

In Scrum, each ceremony has its own importance, and this also applies to the sprint’s retrospective meeting. Once the team has finished the sprint, it’s time to talk about what just happened. There are many ways to do this, but the one we have found to be very useful is answering three simple questions:

  • What should we continue doing?
  • What should we stop doing?
  • Are there any ideas to improve as a team?

A common mistake is to skip this ceremony under the excuse that is not as important as the other ones, and that the team can use that time for a more meaningful activity. But remember, if something went wrong during the previous sprint and the team didn’t have a discussion about it, chances are it will happen again soon. I saw one example of this when a team had had a couple of sprints without delivering much value. From the Scrum Master’s perspective, the obvious reason was because the Product Owner was adding features at the middle of the sprint. Because of the rush, the team had been skipping the retrospective for 3 weeks in a row under the excuse that there were urgent bugs to deliver. When I was invited to analyze the situation, I gathered all the team members to talk about the project’s issues, and one team member wrote down that the technical debt of the project was making it difficult to incorporate new features. By talking about that, the team realized that they should have focused their effort on solving that situation first, and that once they had solved it, adding features  mid sprint was not going to be a problem anymore.

After a couple of sprints I took a look at the project again, and it turned out that they were delivering features and that the sprint disruptions reduced a lot. We can see here that the Sprint Retrospective is a valuable ceremony for the Scrum process, and that if the team talks about the issues that they are having, they can improve their performance and the value delivered each sprint.

Final thoughts

It is true that the Scrum Master is the guardian of the methodology, and that he or she should lead the process, but a successful project involves more than excellent work from the Scrum Master and well defined requirements. Scrum is a methodology that helps the team to succeed in the software development process, but it requires that every team member is committed to support it.

Thanks to my friend and co-worker Jonatan Juarez who contributed on the creation of this post.

Want to know more about running Agile on your organization? you can contact me by e-mail or follow me on twitter

1 9 Continue Reading →

Testing your application on IE with Mac OS X

Today I’d like to show you how to test your web apps on Internet Explorer by binding a Virtual Machine running Windows with Mac OS X. I’ve learned to do this by experience and I thought some people might find it useful.

What I will cover:

  1. Binding the Virtual Machine with Mac OS X
  2. Testing once you have setup VirtualBox.
  3. Fixing CSS3 and HTML5 compatibility

 

So, let’s get started…

Binding the Virtual Machine with Mac OS X

  1.  Install virtual box on mac (https://www.virtualbox.org/wiki/Downloads)
  2. Create the partition and install Windows in your VirtualBox machine, this is going to be your Guest OS (Windows). You can follow this guide to see how to do it.I recommend assigning 4GB of RAM to your VM if possible, otherwise it could run very slow.
  3. You need to be sure that your Guest Machine’s network adapter is attached to the NAT and to do so, go to your VirtualBox app in the Host OS (Mac OSX) and then click on “settings”, after that click on “network”. Make sure that NAT is selected in ‘attached to’ field.

There are two ways to check the address of the application:

Using Pow

This is the the approach you have to follow if using domains and subdomains is a requirement in your app.

  1. Install Powder gem in order to link your projects and navigate on the browsers as “real” domains. Open your terminal and go to your project and code “gem install powder” then “powder link”. Now your application is available at http://your-app.dev/ finally open your application with “powder open”
  2. In order to see the application with the “real” domain you have to add an item to the hosts file. Go to your Guest’s OS and add the host to the list.Here’s how: http://www.rackspace.com/knowledge_center/article/how-do-i-modify-my-hosts-file

Without Using Pow (two ways)

You can use your Host OS’ IP address directly to configure your Virtual Machine doing this:

Using the IP directly
  1.  Go to your “terminal” in your Host OS (Mac OS X) and type “ifconfig” in order to get the ip (copy the ip next to the “inet” word in the “en1” block).
  2. Copy the ip in the address browser with the port that you are using. For example: http://192.168.1.212:3000 (where 192.168.1.212 is the IP address and 3000 is the port where my app is running).
Assigning a static ip to the guest OS (recommended)

I recommend this option to avoid having to look at your IP address every time you are running your Virtual Machine.

  1.  Follow instructions on this link. If you don’t find the vboxnet0, check how to fix it on this link, and if you have an error trying to add the vboxnet0 network then execute this in your Mac terminal: sudo  /Library/StartupItems/VirtualBox/VirtualBox restart.
  2. Now check that your Guest OS is linked to your Host OS by typing the next IP address in your Guest OS browser’s address bar: 192.168.56.1. If everything worked you should see your Host OS’ localhost (make sure your localhost is running in your Host machine).
  3. As a fancier option, you can do this: in your Guest OS click on the Windows icon and then do right click on Notepad; select Run as administrator. In Notepad click on the File menu and then Open, after that paste C:\Windows\System32\drivers\etc in Notepad’s address bar. Once you are in \etc select the All files option so you can see the host file. Select host file and click open. Add an alias for 192.168.56.1, that way you can use domains in the Guest OS’ browsers instead of using the IP address. Don’t forget to specify the port right after the new URL in your browser, e.g. http://mylocalhost.com:3001.

 

As a final tip, pay attention to browser’s address bar if you are working on a project that is composed by several apps using the same domain. You have to make sure that you remain always under the same domain (the one you added on your host file in your Guest OS), otherwise communication between your apps will break. In my experience, I was working on a project that apparently was not working, but that was because requests from myapp.com:3000 were not being delivered correctly to myapp.com:3001 and the issue was that myapp.com:3000 was sending requests to anotherdomain.com:3001.

Testing after setting up VirtualBox

Testing and fixing styling issues is not that hard. Next I’m going to mention some libraries and tips that will help you to fix cross-browsing issues.

  1. Install utilu, which allows to have multiple standalone versions of the IE browser. Also install IE9 on your Guest OS.
  1. Open the website on IE and Google Chrome then make a comparison between them. Try to identify two main things (navigate through the application page by page), functionality and styling. Functionality could be video playing function, clicking a button and seeing what happens, styling could be that the buttons are in the wrong place, the border looks different, etc.
  1. Navigate through the application page by page and take screenshots of the issues that you find in the revision if they are styling issues. It there are functionality issues then write a description about what the bug is and how to reproduce it (it could be an issue related to Javascript for example).
  2. When you are navigating page by page start the debugging mode on IE, pressing F12 and then selecting the “script” tab. Look for errors related with Javascript that could break your loading page. Also, can check the HTML, CSS and network outputs in order to see if something is wrong.
  3. If you already detected the differences, I recommend you to write them down so you can track them. Since I use pivotal what I do is to open a new ticket for each issue I find.
  4. If you already tested the application on IE9 you can also check the application on “compatibility mode”, to simulate the IE8 version with IE9 by selecting “document mode: IE8 standards” and “browser mode: IE8’. Those options are in the developer tools window (see screenshot).

 

IE developer tools

IE developer tools

 

Now you can test your application on IE7 to IE8, just one thing to keep in mind: what you will see is not an exact copy of what you would see if you installed IE8 or IE7. It is only an approximation. It can help you detect some bugs in a easy and fast way. It’s better and recommended to install the real version or each browser and test the application there.

Fixing CSS3 and HTML5 compatibility

  1. If you detect that some elements (buttons, inputs, text) are in the wrong place, you could check the HTML code using “developer tools” from IE browser (pressing F12).
  1. Inspect the element that is malfunctioning and see the HTML code, check that the code is correct. Remember IE8 doesn’t support HTML5 tags. Like this one:

This is the code that you expect:

<header>I’m Header Text</header>

This is the code that you really have on IE8:

</header>

To solve this problem you can include HTML5 Shiv library inside of your <head> tags.

<!--[if lt IE 8]>

<script src=”html5shiv.js”></script>

<![endif]>

The next example shows how the site looks when you are and when you are not using this library.

Difference between Shiv and Pie

Difference between Shiv and Pie

  1. The next step is checking the CSS3 properties. As you probably know, IE8 doesn’t have the same rules as Moderns browsers, IE8 doesn’t support css3 properties. The solution to fix this kind of issue is installing Pie as a JavaScript library (same as the shiv library inside of <head> tags). In this way we are going to be able to use properties like border-radius, box-shadow, etc.

 

NOTE: bear in mind that those libraries help to improve the style of your website and make your site more compatible with IE, but there are some little variants. For instance, in the box-shadow tag it is not possible to add alpha transparency because it is not supported by the library.

The left image shows how the site would look with the Shiv and Pie libraries.

The left image shows how the site would look with the Shiv and Pie libraries.

  1. Speaking of functionality, you have to check the behavior of your application and make a comparison and fix one issue at the time. Try to be patient and get help from the “developer tools” that IE provides.

 

Some notes:

  1. Look for errors in the “script” console of the developer tools.
  2. Remember that IE does not support some Javascript methods because it runs an old JS version.
  3. Remove “console.log”, it could break your code.
  4. If you are working with videos you can use video.js in order to make videos compatible with IE, using fallbacks. Remember, use a link when flash is not installed instead of an image.
  5. Test your application and make comparisons about the missing elements, and also test in modern browsers because you could break your code without noticing.

 

Well, that’s it! I know it was long but I think it can help someone out there. Please let me know if you have any feedback in the comments section below.

Special thanks to Jaime Gonzalez, who contributed with the creation of this article.

0 4 Continue Reading →

Creating a continuous integration server in a hackathon, and how to make SSH connections using ruby

Rails Rumble wrapped up recently and with that, the end of an exciting 48 hour experience where developers can challenge themselves, prove all their programming skills and create an awesome product from an idea.

This is the third hackathon I’ve participated in since I began working as a professional programmer, and I wanted push myself and create my own version of a continuous integration server.

While creating a continuous integration server we went through a lot of challenges, from user experience design to interesting architectural decisions, but one of the most challenging and interesting situations I went through was running the build jobs from a repository in a virtualized environment. At the very beginning we realized that the safest way to run the tests for a given repository was to isolate the test environment from the web server environment due to because of security risks, so we decided to setup the architecture in the following way:

 

CI2

 

 

 

The idea was to connect to a remote (virtualized) server over the SSH protocol and run the script with a provisioned environment (ruby, rvm, rubygems, postgresql, sqlite, mysql, etc.). We spent some time researching how to connect via SSH using ruby and found a library called Net::SSH which allows you to create SSH connections easily and execute a command. We did some tests and it worked but unfortunately it was very hard to navigate through folders and request a bash environment just like a normal SSH connection from the UNIX terminal, so after a long researching, testing, and reverse engineering many open source projects that use Net::SSH we decided to create abstraction layers for each of its components (use-cases).

 

CI3

 

 

By giving single responsibility to each of the classes we were able to easily build the programming interfaces on top of the CI module (see SOLID).

The simplest case scenario, you can connect to a server just by instancing the objects from the top level class of the CI module as following:

Pretty easy, right? Let’s take a look inside the module:

This class is only responsible for setting up the connection parameters that Ci::SSH will handle as a connection string, so we have encapsulated the Ci::SSH work in a lower level of the Ci namespace. You can actually use it outside the Ci::Environment class but you have to customize it as seen in thedef initialize method above. Now let’s take a look at how the Ci::SSH works.

By defining these two classes the usage of Net::SSH becomes pretty straight forward:

By the end of the hackathon, all this made communication possible between the continuous integration environment and the UI. We connected the shell output to a websocket using the pusherservice, so we could push notifications from the server in real time to the user; you can see it live by visiting the actual project from RailsRumble Simple CI.

Questions?

Let me know via comments on this post or via email antonio@tangosource.com.

0 0 Continue Reading →

What? Rails can’t hear you? Use Flash!

First I’d like to mention that this post is not for beginners, that means that I’m assuming that you know about programing with Ruby on Rails (for this post I’m using Rails 3.1) and some of Javascript. If you don’t know Rails or JS at all, you may need to do some research about the terms and instructions I say here. With that said, lets start!

Have you ever needed to record and save user’s audio by using computer’s microphone using Rails? If so, I bet you realized that there is almost no information about how to do this using Rails.

The Story

I was working in a project where the customer needed to implement a feature to allow users to record his voice by using his computer’s microphone. I thought “this can’t be that hard, there is HTML5 now,” but I had no idea what I was talking about.

Researching: HTML 5 or Flash?

I started researching about HTML5 and it didn’t take me that much to see that HTML5 is an “still in progress work“ when it comes to record live audio. The browser that currently has the best implementation for HTML5 audio tag is Chrome, and yet it needs the user to configure some of its flags for this tag to work properly, so I discarded HTML5 as an option.

I continued researching and soon I started reading in many posts that the best approach to accomplish what I was trying to do was by using Flash in the client side. I know, I don’t like Flash either, but lets face it, most browsers support Adobe plugins and this is better than having the application working only in Chrome, so I decided to give it a shot, and took the Flash & Rails path.

Once I decided to go with Flash, the next impediment I had was that I’m not a Flash programmer, but that was solved when I bumped into the jRecorder plugin (I want to thank to Sajith Amma because he certainly saved me hours learning Flash). jRecorder is a plugin that uses a Flash object to get access to user’s microphone and records the microphone input. This plugin has also an API built in javascript to initialize and interact with the Flash object.

Ok, enough background, let’s jump into the interesting part:

Coding

Download the jRecorder plugin, and unzip the file. You’ll see 7 files; the ones we need are: jRecorder.js, jRecorder.swf, and jquery.min.js

In your Rails application:

Explaining the code

This is the DOM’s object where the flash object will be inserted.

The js code is actually the constructor of the js object that will interact with the Flash object (we can say it is a sort of an API). You can read the documentation of the plugin here, however there are 2 parts that I would like to explain since the example that our good friend Sajith implements is in PHP and you may get confused:

In ‘host’ we are defining the route where we want to receive the recorded audio, in this case, for my application <%= audio_path %> points to a controller named audio in the action upload_file that we’ll use to save the audio file. You can create a different route, just make sure it uses the POST method because we are sending information to the server, and filename=audio.wav is a parameter that contains ONLY the name (that means NOT the recorded audio). The result of “<%= audio_path %>?filename=audio.wav” would be something like ‘/audios/upload_file?filename=audio.wav’.

The other interesting option that you need to translate in the example from PHP to Rails is ‘swf_path’. This option is where you set the path of where jRecorder.swf object is located, and all you have to do is to use Rails helper ‘asset_path’ and pass to it the name of the flash object.

At this point we are done with the client side.

Jumping into the backend

Go to the controller that responds to the route that you specified in ‘host’ parameter in the js code, in my case it’s the action upload_file in audios_controller.rb. If you already read the jRecorder documentation that means that you’ve seen this:

(PHP code)

This code is very self-explanatory and you can infer that all this code is doing is receiving the recorded audio, opening a file, writing the recorded audio, and closing the file. Now, what is the equivalent code in Rails? Here it is:

The interesting line here is ‘request.raw_post’. That line contains the actual audio recorded by the user that was sent by our view using the plugin. That line is the equivalent of ‘file_get_contents(‘php://input’)’. Also check that we are opening the file with ‘b’, which is very important because the file we are reading/writing is a binary file (otherwise you’ll face encoding issues).

That’s it! You should now have the file stored in the root path of your application!

Improve it

Depending on your application, there are many things that you can improve, like converting the file from .wav to .mp3 or .aac formats using Zencoder, uploading the file to S3 buckets, implement background jobs to save the audio, etc.

Got questions?

Let me know in the comment section below.

0 0 Continue Reading →