Skip to main content

Mobomo webinars-now on demand! | learn more.

Jobs
So you're applying for your first job, or you've been around the block and are looking to join a new, exciting team. Congratulations on this new chapter in your professional life!

Applying for a job is a little bit like selling a car. Make sure what you're selling is presentable, that the paperwork is in order, and that your advertising brings potential buyers through the door. I've been through the interviewing process (on both sides) for UX/UI designers, Ruby on Rails, and as of late, Angular developers and have quickly picked up on what works (and what doesn't). Below are a few helpful tips as you navigate the job application journey...

Cover Letter

Don’t skip this one. Call me old fashioned, but the cover letter is the first impression you will make. It doesn’t have to be long or very detailed. Include something you saw or heard about the company to which you are applying. Quick example- “I have seen your open source contribution on GitHub and I would love to work for a place that supports open source.” I think of the cover letter as stepping into your in-laws' house for the first time. Would you walk in, and without saying a word, sit down on the couch? Probably not. Unfortunately, a lot of people don’t send cover letters. Don’t be one of them.

Your Work

There is a saying, "You are as good as your last project”. Make sure your latest and best work is easily seen. Provide working URLs, or links to GitHub repos, and a little bit of information about your role. If you don’t have active apps or websites to check out, provide screenshots or code examples instead. If you are fresh out of school or your current job did not lead to a portfolio, design or build something on your own that you can show. Applying for a job without work examples immediately puts you at a disadvantage, no matter how good your resume is. Invest some time into presenting your latest work. This is your opportunity to show your skill and passion. It will pay off for many years to come.

Resume

Simple is smart. Keep your resume in a simple and easy-to-read layout. Most likely, your resume will be read on a screen and not on paper. Keep that in mind when you select fonts and font sizes. Don’t go overboard and design a resume that looks like a brochure for a Disney cruise. Have your resume available in Word and PDF format. PDF will look nicer because you can use custom fonts. Some large businesses want you to submit an editable word doc, not a PDF. At Intridea, we are happy to accept your nicely formatted PDF resume. Thank you :)

  • Include your full contact info and include your LinkedIn URL if you have an account.
  • Give your resume a file name that is useful, for example: FullName-Resume.pdf
  • Attach a page with a list of your latest work.

Don’t create a long list of every programming language and server technology under the sun. It is not impressive. Instead, it shows a lack of focus and raises the question, "What is she/he really good at?" Good example: If you are applying for a Ruby on Rails developer position, make sure your Ruby on Rails experience is listed first and highlighted. If you have experience in other programming languages and frameworks, list them in a separate paragraph.

Meetings & Communications

Most likely, your first meeting will happen over the phone. Make sure you are in a quiet place and your voice is coming through loud and clear. Calling from Starbucks while you are waiting for your Grande Mocha won’t be impressive. In the days of Skype and GoToMeeting, don’t be afraid to hop on a web meeting with video. When you receive emails, reply promptly with simple language. Don’t reply with novels. When you are invited for a face to face meeting, dress appropriately. Better to be overdressed then under dressed.

Salary

Now to the big question. What to say when your new employer is asking you about your future salary? Don’t stay quiet. If you do, mostly likely the employer will offer a salary that is under market value. Do your homework. Research the position you are after and find out what a fair salary is based on your location and experience. With a little bit of intel, you will feel more confident asking for your future salary and it shows your new employer you know your industry.

Good luck and if you are looking for a new position as Angular, Ruby on Rails developer, or UX/UI designer apply here: http://jobs.intridea.com/

Categories
Author

This article originally appeared on the Divshot blog. Divshot is a developer-focused platform for deploying modern front-end applications. It was also started with Intridea's support by Michael Bleigh!
Web Components are a collection of standards that allow folks to bundle markup and styles into custom HTML elements. They enable truly encapsulated and reusable components for the web and we just can't get enough of 'em at Divshot.

Thus, we'd like to share a little with you! Below are two screen-casts from our monthly Web Components Meetups. Enjoy.

Web Components, a Crash Course

We believe that web components are the future of web development. It's the front-end execution of compartmentalizing app architecture components.

In this video, I'll walk you through what web components are, how to use them, and why they matter, all in under 40 minutes.

Styling Web Components w/ Polymer

The beauty of Polymer components is how easy it is to style them and shipped as a single drop-in element. Jake Johnson walks you through the Shadow DOM and the included powerful tools for building a clean UI.

Got any questions, ideas, thoughts? Let us know!

Categories
Author

This article originally appeared on the Divshot blog. Divshot is a developer-focused platform for deploying modern front-end applications. It was also started with Intridea's support by Michael Bleigh!

If you're diving into Polymer and the new world of Web Components, you may be wondering how to organize and structure your project. We don't have all the answers, but here's what we've found so far.

The structure of an application can be just as important for developer productivity as the frameworks and technologies upon which it's built. When something entirely new (like Polymer) comes along, it can take some time to settle into best practices. At Divshot we've been building small apps and a few larger ones using Polymer for the past year or so. This post summarizes what we've learned thus far about structuring apps.

Note: This isn't an introduction to Polymer but an exploration of best practices for those already using it. Try the official tutorial for a proper intro.

The Basic Structure

When we start building a Polymer app, we don't start with a complex generator toolchain. In fact, we don't start with a build process at all. It can make sense to add one in later depending on how large and complex your app gets, but Web Components are browser-native and it's nice to be able to take advantage of that!

The directory structure of our Polymer apps start something like this:

public/   bower_components/   components/   index.html .gitignore bower.json divshot.json README.md 

Pretty self-explanatory. The divshot.json is there for hosting on Divshot (of course), but also to use its custom routing to make index.html work for any URL during local development in true Single-Page App fashion.

Our .gitignore simply makes sure that we aren't checking in the contents of our Bower install:

/public/bower_components 

Bower is Your Friend

If you want to be productive, you absolutely need Bower. It's how the Polymer team is managing their own code, and you won't want to fight it.

So make sure you run bower init and create a .bowerrc file in your project's directory that points to the proper place. For many of our projects, the .bowerrc looks like:

{"directory":"public/bower_components"} 

If you plan to use Polymer UI Elements or Paper Elements, each comes with a "Kitchen Sink" package that installs all of its elements. While useful during development, you're unlikely to use every single one of them. There's a trick to make this easier: install the aggregate packages locally for development, but only add to bower.json the specific ones that you're using. So start with:

bower install Polymer/paper-elements bower install PolymerLabs/polymer-ui-elements 

And the first time you use one of the components (e.g. paper-ui-button) in your app, install it to your bower.json:

bower install --save Polymer/paper-ui-button 

Naming Elements

We've found it to be a helpful practice to come up with a short prefix that you apply to all of your application specific elements. This might just be app, but probably works better with your actual application name. For example, Polymer's Topeka example app prefixes its elements with topeka-.

Managing Element Dependencies

The public/components directory is where you'll be placing all of the custom elements that you build. In the beginning, this will likely be a simple list of .html files named after the elements, potentially with .css files to go along with them. A typical file will look like:

 <link rel="import" href="../bower_components/some-element/some-element.html"> <link rel="import" href="app-another-element.html">  <polymer-element name="app-my-element">   <template>     <link rel="stylesheet" href="app-my-element.css">        </template>   <script>     Polymer('app-my-element', {       // ...     });   </script> </polymer-element> 

Your dependencies will either come from inside the components directory or from your bower_components. It's your call whether to use absolute (e.g. /bower_components/some-element/some-element.html) or relative (e.g. ../bower_components/some-element/some-element.html) paths. Each has advantages and drawbacks, and we haven't settled on a clearly superior option yet.

You should always import all required dependencies at the top of an element. Even if you are using the same element in many files, you should have an import link at the top of each one. This way if you move things around, you won't accidentally break dependencies.

The only exception we've carved out to this rule is polymer.html which we directly import in the index.html file just after platform.js since every element we build requires it.

Alternative: Separate Elements Repository

Again referencing the Polymer teams' Topeka app, they to created a separate topeka-elements repository for all of their app's custom elements. While we can only speculate, it's likely that they did this so that they could install all the elements with Bower and consistently use relative path imports (e.g. ../some-element/some-element.html) in their code.

There are definitely advantages to this method, and it's one we're evaluating to see if it feels superior or more productive. The greatest challenge is in the need to constantly commit to two repositories that are tightly coupled as your application grows and changes.

Building Reusable Elements

Web Components are composable and reusable like nothing that has come before. In the course of making your app, you're likely to come up with a few elements that could easily be used for other purposes. The Polymer team has a great guide on creating reusable elements that we highly recommend, but it can be tough to work on one in the context of a larger app. Here's how we do it:

  1. Follow the linked guide above, but put the project folder for your new element inside public/bower_components.
  2. Initialize it as a separate git repository. Since its parent folder is ignored by git, you won't have a conflict in doing this.
  3. Publish your new element to GitHub. You don't have to register it with Bower just yet.
  4. Manually add a dependency to your bower.json for your new reusable component.

So long as you remember to push your changes up from your reusable component, your colleagues will be able to install it alongside all their other Bower dependencies.

Bundling Elements

One of the biggest "a ha!" moments we had while planning out structure was how to manage groups of related components. The answer was to utilize one of the web's oldest features: the directory index file!

As you begin to group elements together (maybe by feature, by function, whatever makes sense to you) you can create subdirectories in your public/components directory to house them. Then just create an index.html file that imports all of the grouped components. For example:

 <link rel="import" href="blog-post.html"> <link rel="import" href="blog-category.html"> <link rel="import" href="blog-comments.html"> 

Now when you want to be able to use these related elements, you can do so with a single import:

<link rel="import" href="components/blog/"> 

It's when you do things like this that you understand just how wonderfully well-designed the Web Components architecture is, and how well it fits into the existing HTML world.

Concatenation and Build Process

Most of our apps are still in the development phase and not quite ready for public consumption. As such, we don't have deep experience with trying to optimize Polymer apps for speed or network performance (yet).

Vulcanize is going to be a good place to start looking, though.


These are some of the tips and tricks that we've learned so far. Are you building Polymer apps? If so, what have you learned to be as productive as possible? Let us know!

Categories
Author

Angular

In Part I of our Angular series, we illustrated the process for setting up an Angular app for Rails.

In Part 2 of this series, we'll be creating a basic HR app. This app will allow us to view employee information through an Angular app (edits and updates to be explained in Part 3 of this series). For more details, see code in Github link at the end of post.

Here's a quick snapshot of what we'll be creating for our HR app:

  • Setting up test frameworks
  • Creating a Rails API
  • Making the Angular frontend talk to the Rails API

Setup RSpec

First, remove the test/ directory. This is left over from our initial app setup in Part 1: How to Set Up Angular with Rails. Then add RSpec and factory_girl_rails to the Gemfile:

group :development, :test do   gem 'rspec-rails', '~> 3.1.0' end  group :test do   gem 'database_cleaner'   gem 'factory_girl_rails' end 

Next, bundle and install it.

bundle install rails generate rspec:install 

And edit your spec/spec_helper.rb to match:

ENV["RAILS_ENV"] ||= 'test' require File.expand_path("../../config/environment", __FILE__) require 'rspec/rails' require 'rspec/autorun' require 'database_cleaner'  ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration) RSpec.configure do |config|   config.include FactoryGirl::Syntax::Methods   config.infer_spec_type_from_file_location!    config.expect_with :rspec do |expectations|     expectations.include_chain_clauses_in_custom_matcher_descriptions = true   end    config.mock_with :rspec do |mocks|     mocks.verify_partial_doubles = true   end end 

Create the Employee Model

Let's create the Employee model with a few fields:

bundle exec rails generate model Employee name:string email:string ssn:string salary:integer bundle exec rake db:migrate 

Next, we'll add some validations in app/models/employee.rb:

class Employee < ActiveRecord::Base   # regex taken from Devise gem   validates_format_of :email, with: /A[^@s]+@([^@s]+.)+[^@s]+z/   validates_format_of :ssn, with: /d{3}-d{2}-d{4}/   validates_presence_of :name   validates :salary, numericality: { only_integer: true } end 

Before creating the API interface for Angular, let's create a serializer for our Employee model. This will allow our API to expose only those fields that are necessary to Angular frontend. Add ActiveModel Serializers to the Gemfile

gem 'active_model_serializers' 

And bundle install

Create the Employee API

In order to support the Angular frontend, we'll need to create an API controller at app/controllers/api/employees_controller.rb:

class Api::EmployeesController < ApplicationController   respond_to :json    def index     serialized_employees =       ActiveModel::ArraySerializer                .new(Employee.all, each_serializer: EmployeeSerializer)      render json: serialized_employees   end end 

Now we need to define that EmployeeSerializer in app/serializers/employee_serializer.rb:

class EmployeeSerializer < ActiveModel::Serializer   attributes :id, :name, :email, :ssn, :salary end 

And expose this API to the frontend in config/routes.rb:

Rails.application.routes.draw do   get 'example' => 'example#index'    namespace :api do     resources :employees, defaults: { format: :json }   end end 

Finally we'll add some Employee data to db/seeds.rb:

Employee.create(name: "MacGyver", email: "test@example.com", ssn: "555-55-5555", salary: 50000) Employee.create(name: "Calhoun Tubbs", email: "test2@example.com", ssn: "123-45-6789", salary: 60000) 

Seed the database and start the Rails server:

bundle exec rake db:seed rails s 

Then we can open http://localhost:3000/api/employees in the browser which will return:

[   {     "id": 1,     "name": "MacGyver",     "email": "test@example.com",     "ssn": "555-55-5555",     "salary": 50000   },   {     "id": 2,     "name": "Calhoun Tubbs",     "email": "test2@example.com",     "ssn": "123-45-6789",     "salary": 60000   } ] 

Test the API

Now that we've verified this action is set-up correctly, let's add a factory at spec/factories/employees.rb:

FactoryGirl.define do   factory :employee do     name 'Test Employee'     email 'test@example.com'     salary 50000     ssn '123-45-6789'   end end 

Next, add a test at spec/controllers/api/employees_controller_spec.rb:

require 'spec_helper'  describe Api::EmployeesController do   before(:each) do     create(:employee, name: 'Calhoun Tubbs')   end    describe '#index' do     it 'should return a json array of users' do       get :index       result = JSON.parse(response.body)        expect(result[0]['name']).to eq('Calhoun Tubbs')     end   end end 

While the above test is somewhat trivial, this set up is great for verifying more complex logic in real world applications. In addition, the reason for adding an API spec prior to the Angular portion is to avoid playing the guessing game if/when problems arise; waiting to add the Angular framework helps to ease the deciphering process. If your Angular app isn't working correctly, its important to verify that the Rails backend is also behaving correctly -- the problem may not be an Angular issue.

Create the Angular frontend

You may want to take a look back at Part 1: How to Set Up Angular with Rails to review how we setup the AngularJS frontend with Rails. Let's start by defining an app in app/assets/javascripts/angular-app/modules/employee.js.coffee.erb:

@employeeApp = angular   .module('app.employeeApp', [     'restangular'   ])   .run(->     console.log 'employeeApp running'   ) 

Next, we'll define the Employees controller in app/controllers/employees.rb:

bundle exec rails g controller Employees index 

Then, we'll add to the beginning of config/routes.rb:

root 'employees#index' 

Finally, let's start the Angular app in app/views/employees/index.html.erb:

<div ng-app='app.employeeApp' ng-controller='EmployeeListCtrl'> </div> 

If you run the Rails server and hit http://localhost:3000/ you'll get an error about the controller not being defined yet in the javascript console. Before we create the controller, let's setup a Employee model and service to handle fetching Employee records from the Rails API.

The Employee model is defined at app/assets/javascripts/angular-app/models/employee/Employee.js.coffee:

angular.module('app.employeeApp').factory('Employee',[() ->   Employee = () ->    return new Employee() ]) 

There is no special behavior here yet. It is only returning the data that comes from the API.

To ease the process of working with APIs in Angular, let's add the restangular library to our project. In bower.json add restangular:

  "lib": {     "name": "bower-rails generated lib assets",     "dependencies": {       "angular": "v1.2.25",       "restangular": "v1.4.0"     }   }, 

Then run bundle exec rake bower:install. Next, we need to add restangular and its dependency lodash to app/assets/javascripts/application.js:

//= require jquery //= require jquery_ujs //= require angular //= require angular-rails-templates //= require lodash //= require restangular 

Afterwards, we'll create the Employee service at app/assets/javascripts/angular-app/services/employee/EmployeeService.js.coffee:

angular.module('app.employeeApp')   .factory('EmployeeService', [     'Restangular', 'Employee',     (Restangular, Employee)->        model = 'employees'        Restangular.extendModel(model, (obj)->         angular.extend(obj, Employee)       )        list: ()     -> Restangular.all(model).getList()   ]) 

Finally, let's create the controller at app/assets/javascripts/angular-app/controllers/employee/EmployeeListCtrl.js.coffee:

angular.module('app.employeeApp').controller("EmployeeListCtrl", [   '$scope', 'EmployeeService',   ($scope, EmployeeService)->      EmployeeService.list().then((employees) ->       $scope.employees = employees       console.dir employees     ) ]) 

If you run the Rails server and visit http://localhost:3000/ in the javascript console you'll see a print out of the Employee objects previously seeded to the database. Next, let's add to the template code to show our Employee objects. In app/views/employees/index.html.erb:

<div ng-app='app.employeeApp' ng-controller='EmployeeListCtrl'>   <table ng-if="employees">     <thead>       <th>Name</th>       <th>Email</th>       <th>SSN</th>       <th>Salary</th>     </thead>     <tbody>       <tr ng-repeat="employee in employees">         <td>{{employee.name}}</td>         <td>{{employee.email}}</td>         <td>{{employee.ssn}}</td>         <td>{{employee.salary | currency}}</td>       </tr>     </tbody>   </table> </div> 

Open http://localhost:3000 and notice the salary field. We used the currency filter to handle formatting that data. Salary comes back from the API as a plain integer value. Angular has a number of useful filters that are included by default.

The above example is very basic. However, we created database objects, exposed those via an API, tested the API, and created an Angular app to handle the frontend. That's no small task! A few pieces are still missing though. While our Ruby API has tests, our Angular app has no tests at all. Furthermore, our employee management app is view-only.

Github code for HR app here.

In Part 3, we'll setup javascript tests, and add editing functionality to our Angular frontend. In the meantime, review Part 1 and if you have any questions feel free to message us on Twitter.

Categories
Author

This article originally appeared on the Divshot blog. Divshot is a developer-focused platform for deploying modern front-end applications. It was also started with Intridea's support by Michael Bleigh!
Motion is quickly becoming one of the most important emerging techniques in building a quality user experience on the web. Angular 1.2, currently in release candidate form, provides an overhaul of Angular's animation system and makes it spectacularly easy to bring your interface to life.

Of course, hand keying animations can be time consuming especially when you're trying to prototype something in quick order. Luckily, Animate.css provides a library of ready-to-go animations that can be dropped in quickly and easily. But how can we use these together?

Introduction to Angular 1.2 Animations

Animations in Angular 1.2 take a very simple convention-based approach. Here's basically how it works:

  1. Angular automatically detects and triggers animations based on certain events (namely enter, leave, and move)
  2. When one of those events occur, Angular automatically attaches a special class to the element (for example ng-enter when a new item is added to a list, for example)
  3. This class can be used for setup (for example, to set attributes for the "before" of a transition), but after this class is applied another class is applied (ng-enter-active, for example) to indicate that the animation should begin.
  4. The ng-{event} and ng-{event}-active classes are removed automatically after the animation concludes (determined by introspecting the CSS and determining transition duration)

This all sounds relatively complex, but it's actually quite simple in practice. Basically, for a custom animation you would just need to define some CSS like so (vendor prefixes omitted for brevity):

.some-element.ng-enter {   transition: height 1s;   height: 0px;   overflow: hidden; }  .some-element.ng-enter-active {   height: 100px; } 

The above code would automatically resize an element from zero height to 100px over the course of 1 second when the "enter" event is triggered.

Animating on CSS Class Changes

In addition to events like enter and leave, Angular provides the ability to attach animations to the addition and removal of any class. One of the most common ways would be for show/hide. If I have:

<div class="fader" ng-hide="checked">Animate this!</div> 

This works basically the same as if I had this:

<div class="fader" ng-class="{'ng-hide': hidden}">Animate this!</div> 

To trigger animations when classes are added and removed, you just apply transitions or animations to the class name with -add and -remove postfixes. Here's an example of how I might make a fading animation for ng-hide:

.fader.ng-hide-add {   opacity: 1.0;   display: block !important;   transition: opacity 1s; }  .fader.ng-hide-add-active {   opacity: 0; } 

Activating Angular 1.2 Animations

To use animations in your Angular code, you will need to include the separate angular-animate.js file. If you're using Google's CDN, you can include both Angular 1.2 and Angular Animation in your code. You will also need to create an angular module that consumes the ngAnimate provider to activate animations:

<html ng-app="myApp">   <head>          <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.2/angular.min.js"></script>     <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.2/angular-animate.min.js"></script>     <script>       var app = angular.module('myApp', ['ngAnimate']);     </script>   </head>   <body>        </body> </html> 

One of the most powerful aspects of Angular 1.2 animation is that you don't have to specifically invoke it; instead, it "just works" when any animation-triggering event happens in your page.

Bringing in Animate.css

But what about that nice library of existing animation we already have with animate.css? Simple: because Animate.css provides named keyframe animations, you simply need to apply the given animation to the element when the appropriate Angular animation class is applied. Here's a simple fade in/fade out scenario:

.my-element.ng-enter {   animation: fadeIn 1s; }  .my-element.ng-leave {   animation: fadeOut 1s; } 

That's seriously all there is to it! You can use any of the named animations from Animate.css in the same manner and it will all work, fast and easy.

To demonstrate how easily this can be accomplished, I used Divshot to quickly snap together a "todo list" interface and added some animations. I've published the result to JS Bin, just click below to see the code.

View Todo List Demo
Got any questions, suggestions, ideas? Keep the conversation going! We'd love to hear from you.

Categories
Author

dear maggie

The benefits of remote working are tremendous; from flexible schedules and commuter free work days to working in your pajamas! At Intridea, we are huge proponents of this lifestyle and have written loads of articles on working effectively, and communicating efficiently in it. However, there's one topic that's gone unnoticed, the relational side of remote working. As a five year veteran, Maggie has experienced many of the relational pitfalls remote working can come with and has heard the same from many of her peers. Thus, she and Intridea have decided to do something about it...

Introducing - “Dear Maggie” - a resource for remote workers who may be facing the friction that can often surface when your home becomes your full time office.

Send your burning questions over to dearmaggie@intridea.com, and we’ll address them!


Dear Maggie,

I recently started working for a company that’s fully distributed (remote). The adjustment has been great and I’m really enjoying my new work situation, there’s only one problem.

My wife works a traditional 9-5 job and is consistently annoyed when she returns home to find I haven’t done any housework. I don’t think this is fair, as she isn’t expected to clean during her work-day, and I’m busy doing my own job during the day.

How can I help her to understand I need to put in 8 hours of work too and can’t do all the cleaning while she’s away?

Annoyed in Annapolis


Hey Annoyed,

One of the hardest parts to adjusting to remote working is negotiating a new normal with your partner. Many times people new to remote working are careful to define expectations for themselves, and for their new employer, but not their significant other. I think we’re both in agreement that your wife’s expectations are unfair; both of you work during the day, yours just happens to be from home while hers is at an office.

However, keep in mind, it may be that your wife is questioning your time at home, because she doesn’t see you clean enough when she is around. Perhaps this is an opportunity to address the split of household duties, and put together an amenable plan.

Here are a few tips to ensure success:

  1. Indicate you’re interested in finding a plan that ensures no one (especially her) feels like they’re doing more than their ½ of the work. This way you’re approaching the conversation from a place of positivity rather than complaining.
  2. Own the goal of coming up with a plan and come prepared! Start a chart to help track duties, or a list of the tasks you’ve identified to keep the conversation productive. After you get it nailed down, post it somewhere where it’s easily accessible by both of you.
  3. Setting your partner’s expectations about what she’ll see you do is only half the battle, be sure to discuss the details of when you prefer to accomplish your ½ of the duties too. This way she doesn’t expect the laundry to be done on Tuesdays when you’d prefer to do it on Sunday mornings. Talking it through beforehand ensures no one is let down.
  4. Stick to it. Whatever you two agree on, you have to hold up your end of the bargain. Setting expectations only helps if you meet those expectations.

Every relationship is different, and I wouldn’t say there’s one “silver bullet” for this problem. Nevertheless setting expectations is always a great start. Working remote adds new variables to a relationship - but it doesn’t have to be overwhelming! Being intentional in both your work and family life can be as simple as a list, conversation, or schedule - just take the time and address these issues head on...

Enjoy this post? Check out the rest of our DISTRIBUTED articles here!

Categories
Author

When it comes to Angular and Rails, there are many ways to set up a project. However when starting out, all these options can be a tad overwhelming…

Over the last few months, I’ve been focusing on project set-ups and have come to find a few favorites. In this post, I'll illustrate one way to use Rails with Angular (see Github links with the example code below).

Create a New Rails App

To get started lets create a new rails app.

gem install rails -v 4.1 rails new angular_example 

In this app, I chose not to use turbolinks. It's possible to use Angular with Rails and turbolinks, but the Angular app bootstrap process is more complex. I find that turbolinks and Angular serve the same purpose, which is to make the app respond faster. Adding turbolinks, in addition to Angular, adds a lot of complexity and not much benefit.

Remove Turbolinks

Removing turbolinks requires removing it from the Gemfile.

gem 'turbolinks' 

Remove the require from app/assets/javascripts/application.js

//= require turbolinks 

Add AngularJS to the Asset Pipeline

In order to get Angular to work with the Rails asset pipeline we need to add to the Gemfile:

gem 'angular-rails-templates' gem 'bower-rails' 

Next, we can install these gems into our bundle.

bundle install 

We added bower so that we can install the AngularJS dependency.

rails g bower_rails:initialize json 

When adding Angular to bower.json, I prefer to specify the most recent version rather than going with the "latest". This avoids having your app randomly break when a new version is released and your bower installs again.

{   "lib": {     "name": "bower-rails generated lib assets",     "dependencies": {       "angular": "v1.2.25"     }   },   "vendor": {     "name": "bower-rails generated vendor assets",     "dependencies": {     }   } } 

Now that bower.json is setup with the right dependencies, let's install them:

bundle exec rake bower:install 

Organize the Angular App

At this point we'll create the following folder structure in app/assets/javascript/angular-app:

templates/ modules/ filters/ directives/ models/ services/ controllers/ 

This structure is only a convention and is not enforced by Angular (unlike file naming and organization in Rails). This project structure allows for a single web app to be easily composed of multiple smaller Angular modules rather than one giant Angular app for the whole site.

In app/assets/javascripts/application.js add Angular, the template helper, and the Angular app file structure. That file should now read like this:

//= require jquery //= require jquery_ujs //= require angular //= require angular-rails-templates  //= require angular-app/app //= require_tree ./angular-app/templates //= require_tree ./angular-app/modules //= require_tree ./angular-app/filters //= require_tree ./angular-app/directives //= require_tree ./angular-app/models //= require_tree ./angular-app/services //= require_tree ./angular-app/controllers 

Bootstrap the Angular App

Next, we'll setup the Angular app bootstrapping. Create app/assets/javascripts/angular-app/app.js.coffee:

@app = angular.module('app', [   # additional dependencies here, such as restangular   'templates' ])  # for compatibility with Rails CSRF protection  @app.config([   '$httpProvider', ($httpProvider)->     $httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content') ])  @app.run(->   console.log 'angular app running' )  

Then, we'll create an Angular module at app/assets/javascripts/angular-app/modules/example.js.coffee.erb

@exampleApp = angular   .module('app.exampleApp', [     # additional dependencies here   ])   .run(->     console.log 'exampleApp running'   ) 

Following the Angular module, we'll create an Angular controller for this app at app/assets/javascripts/angular-app/controllers/exampleCtrl.js.coffee

angular.module('app.exampleApp').controller("ExampleCtrl", [   '$scope',   ($scope)->     console.log 'ExampleCtrl running'      $scope.exampleValue = "Hello angular and rails"  ]) 

Now we need to add a route to Rails to pass control over to Angular. In config/routes.rb:

Rails.application.routes.draw do   get 'example' => 'example#index' end 

Next, we'll generate the Rails controller to respond to that route:

rails g controller Example 

In app/controllers/example_controller.rb:

class ExampleController < ApplicationController   def index   end end 

In the view we need to specify which Angular app, and which Angular controller will drive this page.

In app/views/example/index.html.erb:

<div ng-app='app.exampleApp' ng-controller='ExampleCtrl'>   <p>Value from ExampleCtrl:</p>   <p>{{ exampleValue }}</p> </div> 

To view the app, start your Rails server and visit http://localhost:3000/example

You can find the code generated here https://github.com/rawsyntax/rails-angular-example

Categories
Author

Friction: it exists in virtually every company, distributed or not. Whether two team members can never see eye to eye or a manager and her employee just rub each other the wrong way, friction is an ever-present danger in the business world.

“Machines, human or otherwise, need to be maintained in order to run properly,” writes Merle Rein, certified mediator and conflict resolution trainer. “As managers, we are the lubricant, the substance that can reduce friction when it exists.”

If you want to cultivate a collaborative culture, it’s essential to cut through the tension and ensure your distributed team runs like a well-oiled machine. Here at Intridea, we follow four proven techniques to curtail friction within our team.

Friction Reducer #1: Don’t Overdo the Process

If you want employees to be self-driven and go above and beyond what's expected of them, the worst thing you can do is saddle them with a burdensome, overly complicated process. After all, nothing will kill creativity more quickly than a stringent set of convoluted procedures.

When you force employees to adhere to rigid guidelines, they’ll only do what’s required by that process—nothing more. This will box them in to a limited set of solutions, and they’ll be afraid to break through boundaries or even scribble outside of the lines.

According to Teresa Amabile’s research with her Harvard University team, external restrictions almost always squash creative thinking. These outside restrictions include everything from rigorous rules and overly complex processes to leaders implying that new ideas are unwelcome.

Too much process not only smothers creativity—it also suppresses self-motivation. “In today's knowledge economy, creativity is more important than ever,” writes Amabile in a Harvard Business Review article. “But many companies unwittingly employ managerial practices that kill it. How? By crushing their employees' intrinsic motivation—the strong internal desire to do something based on interests and passions.”

Amabile points out that managers don't intentionally slaughter creativity and motivation. Yet in the pursuit of productivity, efficiency and control, leaders inadvertently trample these desirable employee attributes.

Remember: as a distributed team leader, your goal is to hire self-motivated people and nurture that behavior. Yet, an overwrought process will quickly extinguish that behavior. When employees have to jump through hoops to get something done, they're less likely to try.

Friction Reducer #2: Don’t Micromanage

We covered the dangers of micromanagement in an earlier blog, but it’s worth mentioning again. If you want a team of skilled thinkers tackling problems in creative ways, you should never micromanage. Micromanaging will eventually turn a team of self-driven, autonomous employees into an army of robots. Trust your employees, back off and allow them to make their own decisions.

Friction Reducer #3: Embrace Autonomy

At Intridea, we make a point to give our team members the independence to tackle problems and make decisions on their own. If employees have to run every single detail by their manager or gauntlet of others, this slows down their creative process and saps their motivation.

“Well, what if I give an employee autonomy and he screws up?” you might be asking. If a self-driven team member makes a mistake, don’t feel like you have to approve every step he takes from that day forward. Instead, give the employee constructive feedback to steer him in the right direction and then back off. Remember, micromanagement crushes motivation and creativity…so it’s important to give your team members space to accomplish goals on their own.

In fact, research from the University of Washington, Foster School of Business reveals that the key to developing passionate, creative employees is giving them autonomy. “Context is very important,” says Xiao-Ping Chen, a professor of management and organization at the Foster School. “Teams, units and organizations that promote and support autonomous thinking and working will become more passionate. And, in turn, more creative,” he adds.

This heightened creativity will have a major impact on your distributed team’s success. That’s because passionate free thinkers are more likely to take risks that could pay off in huge dividends for your company.

Friction Reducer #4: Don’t Hyper-Focus on Failure

Don't make failure a point of friction. Instead encourage employees to take risks and go above and beyond the call of duty. Of course, employees who take big risks will fail from time to time. However, when you dwell on an employee’s failures, you’ll paralyze her into inaction. Instead of punishing the employee for her mishaps, use them as learning experience for the whole company—not as a point of contention.

“To dwell only on problem areas destroys the employee’s confidence and self-esteem, makes the employee more error-prone,” writes Human Resources expert Susan M. Heathfield. She adds that hyper-focusing on failures will quickly squash an employee’s motivation. “The challenge for employers is not to destroy that intrinsic motivation that every employee has.”

By embracing these four simple tactics, you’ll reduce friction, ignite creativity and cultivate a team of free thinkers.

Got any tactics for reducing team friction? Keep the conversation going! We'd love to hear from you.

Categories
Author
Subscribe to General