Three Reasons Ember.js Closure Actions Rule

Closure actions were introduced in Ember 1.13. They are a huge improvement over the previous action infrastructure. In this post, I’ll highlight some of the things that make closure actions so awesome.

1. Improved Syntax

The old style of action handling was not elegant. Here’s how passing action handlers used to look:


<!-- /templates/components/parent-component.hbs -->
{{old-component someAction='handleAction'}}


// /components/old-component.js
click() {
  this.sendAction('someAction');
}

The parent template passed old-component the someAction property. Then, when old-component sent the action named someAction (via a string), parent-component’s action handler was invoked. The fact that someAction was hooked up to an action in the parent was completely implicit.

The new syntax makes action-passing much more elegant. Here is how we do the same thing now:


<!-- templates/components/parent-component.hbs -->
{{new-component someAction=(action 'handleAction')}}


// components/new-component.js
click() {
  this.attrs.someAction();
}

It’s obvious that when someAction is passed into new-component, it’s an action. When we want to trigger the action, we can just call the function. Another added benefit is that a JavaScript error will be thrown on page load if the component does not define the action hooked up to the template. Before, the error wouldn’t surface until the action was actually attempted.

2. Easier Data Propagation

One of Ember’s core concepts is “data down, actions up” (DDAU). Put simply, data should flow down through an application, and actions (e.g., clicking, typing, etc.) should be responsible for bubbling information back up.

Imagine a scenario where we are displaying a list of superheroes for different comic book publishers. We have a couple of related components. At the very bottom, we have a simple component responsible for displaying and selecting a superhero. When we select a superhero, we need to do some stuff in the application controller, which is at the very top of our application.

Before closure actions existed, we had to bubble that action up through each layer of the application until we reached the top. Every component defined an action that simply sent another action. In other words, it was a lot of boilerplate code.

Closure actions help us avoid most of that boilerplate code. We avoid it by accessing the special attrs property of the component. This object contains all of the attributes passed into a component, including closure actions.

Let’s map out our scenario from the top down.


<!-- /templates/application.hbs -->
{{comic-publishers publishers=publishers selectSuperhero=(action 'selectSuperhero')}}


<!-- /templates/components/comic-publishers.hbs -->
{{#each publishers as |pub|}}
  <h2>{{pub.name}}</h2>
  {{superhero-list superheroes=pub.superheroes selectSuperhero=attrs.selectSuperhero}}
{{/each}}


<!-- /templates/components/superhero-list.hbs -->
{{#each superheroes as |hero|}}
  {{superhero-list-item hero=hero select=attrs.selectSuperhero}}
{{/each}}


// /components/superhero-list-item.js
click() {
  this.attrs.select(this.get('hero'));
}

Because we are leveraging the attrs property, we don’t have to define the boilerplate action handler in superhero-list.js or in comic-publishers.js, and our selection still bubbles all the way up to the application controller.

3. Added Action Currying

Another awesome feature of closure actions is that they support currying. At any level in the chain of components, I can tack additional parameters onto an action.

Revisiting our scenario from above, let’s say the application controller also needs to know which publisher the selected superhero belongs to. That’s easy; we can curry the action in the comic-publishers.hbs template to append the publisher and send that action up to our controller. Let’s check it out!


<!-- /templates/components/comic-publishers.hbs -->
{{#each publishers as |pub|}}
  <h2>{{pub.name}}</h2>
  {{superhero-list 
      superheroes=pub.superheroes
      selectSuperhero=(action 'selectSuperhero' pub)}}
{{/each}}


// /components/comic-publishers.js
actions: {
  selectSuperhero(publisher, hero) {
    this.attrs.selectSuperhero(publisher, hero);
  }
}

Now, whenever the selection bubbles up, the publisher is added to the parameters.

See the Code

All of the code from this post can be found here. I would love to know what other wins you’ve seen from using Ember’s closure actions.

The post Three Reasons Ember.js Closure Actions Rule appeared first on Atomic Spin.

TDD in a REPL, Continued: Read-Eval-PrettyPrint-Loop

Last December, I wrote about using F#’s interactive REPL to facilitate TDD. Since then, enough interesting developments have happened that I think the topic is worth revisiting.

Pretty-Printing Output

REPLs are great, but sometimes the “Print” step can leave a little to be desired. F# has pretty good default REPL formatting for records, lists, etc., but not necessarily for other types, like traditional classes. You can add your own REPL format function for a type, but you’re still limited to string output. For large data structures, being able to expand and collapse the output or view a summary would be very helpful.

Luckily, just such a capability was recently added to the F# REPL–provided you are using the Atom editor. The Ionide F# plugin for Atom was updated to make it support rendering objects to the F# interactive output window as HTML. Basically, instead of providing a formatting function of (YourType -> string) where the string is raw output to display, you provide a function of (YourType -> string) where the output is presumed to be HTML.

Being able to display your data with the standard web technologies (HTML, CSS, and JavaScript) means tons of cool existing frameworks can be brought to bear in your REPL. Check out this repo for some examples of creating tables and graphs with FsLab.

Better-looking Test Results

The update to Ionide helped me address my previously stated goal of creating prettier test output. Since then, I’ve updated my previous TDD script to dramatically increase the ease of reviewing test output. I’ve gone from simple text output that is all in the same color and size to this:
tdd_ionide

In the updated script, I’ve built very lightweight data structures that resemble what a test runner would normally do. Then I turned those structures into some simple HTML and CSS. Eventually, it would be awesome to leverage an existing test runner’s HTML output, but that’s a project for another day.

I’ve created a Github repo for others who would like to use my TDD script for their F# development.

I considered creating a NuGet package for these scripts, but I suspect the desire for consumers to tweak the code will be high enough that just copying or forking the code will be easier. Because there’s nothing to compile, you could alternatively reference the project as a Git submodule to easily get the latest updates.

Choice of Test Framework

I also have an update on one of my caveats from last time. Previously, I was experiencing crashes with the xUnit console runner on Mono. However, because the NUnit assertions do not work without running through the NUnit framework, I had to use xUnit to do TDD in the F# REPL. Even though FsUnit mostly papered over those differences, it still really bothered me.

Lately, though, I discovered the source of my crashes, and it is easy to work around. If you load a project into the console runner, which is of type Exe and not Library, you will occasionally get random crashes. So I just changed my main project to a Library and gave it a thin, untested executable wrapper.

Pretty and Fast

I love being able to change code in a compiled language and see easy-to-read test output instantaneously. The best part is how well it scales. You don’t pay the penalty for compiling the entire project to run one test—or even the cost of starting up the runtime. You only have to send a chunk of the script into an already-running instance of the runtime.

Going Forward

I’d like to see the Ionide changes make their way over to VS Code. Because VS Code has decent F# debugging and a halfway decent Vim plugin, it is within striking distance of being a one-stop shop for F# development for me on OS X.

I’d also like to try and integrate the output formatters for existing test frameworks when possible. xUnit is always going to know how to format their results better than I do. The trick will be getting their formatting code to cooperate in an environment that’s nothing like their test runner.

Being able to make incremental but significant progress in tooling—as I hope I have done by prettifying the output of REPL-based TDD—highlights one of my favorite things about open source software communities. Any contributor can move the ball forward more-or-less independently, and everyone reaps the benefits. Where do you want to make your next contribution to improving the process and practice of making software?

The post TDD in a REPL, Continued: Read-Eval-PrettyPrint-Loop appeared first on Atomic Spin.

Auto-renewal of a Let’s Encrypt certificate

I configured this blog to use a free, automatically-issued Let's Encrypt SSL certificate around 6 months ago.

The command to issue the cert is as follows:

letsencrypt-auto certonly 
  -a webroot 
  --webroot-path /var/www/sites/blog.yo61.com/html/ 
  -d blog.yo61.com 
  --agree-tos 
  --email robin.bowes@example.com

To check if an existing certificate will expire within the next 28 days, use this command:

openssl x509 
  -checkend 2419200 
  -noout 
  -inform pem 
  -in /etc/letsencrypt/live/blog.yo61.com/cert.pem

Put these together, and run from a daily cron job (remembering to restart your web server after changing the certificate) and your cert will automatically renew 28 days before it expires.

openssl x509 
  -checkend 2419200 
  -noout 
  -inform pem 
  -in /etc/letsencrypt/live/blog.yo61.com/cert.pem || 
letsencrypt-auto certonly 
  -a webroot 
  --webroot-path /var/www/sites/blog.yo61.com/html/ 
  -d blog.yo61.com 
  --agree-tos 
  --email robin.bowes@example.com && 
systemctl restart httpd

An Introduction to Website Animation with Velocity.js

Have you tried adding animation to your websites? Introducing motion can delight users, and more importantly, it can be used to provide affordance to information on the page. This post walks you through your first animation, including how to set up your webpage and how to animate a list.

See the Pen Animation Example with Velocity – Main by bryan (@elkusbry) on CodePen.

You can find my full Animation Example with Velocity – Main on CodePen, but I’ll walk you through the details below.

What We Will Use to Make Our Animations

jQuery
Velocity.js
Velocity.js UI Pack

Setting Up

The first thing we want to do is include the JavaScript files in our page. This is done by adding the following to your page inside a script tag. You can choose to host the files yourself or via a CDN. For this example, I included these three files in order via the CDN Links below:

//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js
https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js
https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.ui.min.js

Below is an example of how it might look if you add the scripts inside your HTML file versus using a site like CodePen:
Screen Shot 2016-06-14 at 10.00.28 PM

(You can learn more about including jQuery and JavaScript files here.)

Now, after reloading the page, you should be able to inspect it via the development tools in your browser to make sure that the three files were loaded.

Preparing the Code

We need to wait until the page loads before we can execute the animations. The following jQuery code will do this for us. It waits for the DOM elements to load before executing the code inside the function. In this case, the code will print “ready!” inside the console.

$( document ).ready(function() {
    console.log( "ready!" );
});

(Read more about jQuery’s document ready here.)

This code can be added to the HTML page inside a script tag or by including a custom JavaScript file. If it loaded properly, “ready!” should appear in the web browser’s console.

Starting to Animate

Before we can start animating, we need to tell the code which element(s) in the DOM to animate. I typically leverage jQuery to accomplish this. jQuery will search the DOM elements to find the desired element. This is usually done by using selectors like IDs or classes. So let’s use the code below to tell jQuery to select all the lis on the page.

$("li");

This code selects all the li elements but doesn’t manipulate them, so it’s hard to tell if it really works. To test it, we can output the selections to the console. In the example below, we will select all the li tags on the page and output them to the console.

console.log( $("li") );

In the console, you should see an object listing all the li tags you have selected via the jQuery call.

Creating the Animation

Now that we have the tough part out of the way, it’s time to have some fun animating the DOM elements! You have two options using Velocity; you can create custom animations that manipulate CSS, or you can use the Velocity UI pack. The UI pack has predefined animations for easy implementation. For simplicity’s sake, we will use that and demonstrate it on a list of elements.

Let’s add the Velocity code to the jQuery selection we previously made. To select an animation, I went to the Velocity documentation and tested out which animation to use. For this example, we will use “transition.slideLeftIn”.

$("li").velocity("transition.slideLeftIn");

Polishing your Animation

Velocity gives us two options to tighten up our animations: Drag and Stagger. Using these options in your animations can offer a more fluid and natural feel, especially when animating multiple elements.

Drag alters the duration of each element’s animation in a sequence, which speeds up each of the items, starting from the last item. This animates each element sequentially, instead of animating all the lis at once.

Stagger gives you the option to animate all items at the same time or individually with a set duration between element animations.

$("li").velocity("transition.slideLeftIn", { stagger: 250, drag: true });

In the example below, we animate one list with Stagger and Drag and one without. As you may notice, the lis in the left list all animate in at once, while the lis in the right list flow in nicely. It gives a sense of order and a feeling that the block of content is made up of individual components.

See the Pen Animation Example with Velocity by bryan (@elkusbry) on CodePen.

Endless Possibilities

By now, you have hopefully learned to create your first animation. It’s okay to be choosy about how and when you decide to implement animations, as they can quickly become cheesy and distracting. However, if used correctly, they can bring a nice level of polish to your work. With the combination of selecting elements from the DOM and the immense options to transition CSS attributes, there are endless possibilities for creative animations.

The post An Introduction to Website Animation with Velocity.js appeared first on Atomic Spin.

Exploring UIStackView Distribution Types

Any time you encounter a new tool in your life, it’s a good idea to test it out to see what it can do. In this post, that’s what I’m going to do with UIStackViews. I’ll explore the different distribution types you can set on a UIStackView to see how they behave. That way, the next time I have a layout problem to solve, I’ll understand the UIStackView’s capabilities.

You can find the distribution setting on a UIStackView here.

change_distribution_on_stackviewset_fill_equally_stackview

Fill

This is the default distribution type when you create a new UIStackView. In my test example for Fill, I am using UITextFields and UIImageViews and grouping them in a horizontal UIStackView. UITextFields do not have much of an intrinsic content size—they pretty much collapse down to nothing if you have no text inside them. This will help me demonstrate what effect the Fill type will have.

When you place your controls inside a UIStackView with Fill set as the distribution, it will keep all but one of the controls at their natural size and stretch one of them to fill the space. It determines which control to stretch by noting which one has the lowest Content Hugging Priority (CHP). I added a spacing of eight between the UITextFields so you could see the size of each one.
uistackview-fill
If all of your controls have the same CHP, then Xcode will complain that the layout is ambiguous.

Fill Equally

With this type, each control in a UIStackView will be of equal size. All of the space between the controls will be used up, if possible. I added a spacing of eight between the UITextFields, so again you could see the size of each one. With this type, the CHP does not matter, because each control is the same size.
uistackview-fill-equally

Fill Proportionally

This type was fun to explore. It is hard to see the effect this type has until you play around with different phone sizes and orientations. The UIStackView will ensure the controls maintain the same proportion relative to one another as your layout grows and shrinks. I switched from using UITextFields to UILabels in my test.

Unlike the previous two settings, the Fill Proportionally distribution needs the controls to have an intrinsic content size. The Fill and Fill Equally distribution tell their child controls how big they should be, but this one is the other way around (as long as there is enough space for all of your controls to be their natural size).
uistackview-fill-proportionally
This is what the distribution looks like for portrait and landscape.
uistackview-fill-proportionally-with-landscape
As you can see, the proportions for the images and labels are maintained for the different layout sizes.

Equal Spacing

This distribution type will maintain an equal spacing between each of the controls and will not resize the controls themselves. I have illustrated this by drawing red lines to indicate the equal size of the spacing between the labels and the images.
uistackview-equal-spacing2

Equal Centering

Finally, the last distribution type is a little hard to see without an illustration. It will equally space the centers of the controls. To illustrate this, I drew red vertical lines down the center of each control. The distance between the red lines is spaced out equally.
uistackview-equal-centering2

Those are all of your options when using a UIStackView. They behave quite differently from one another. Some are opinionated about controlling the size of their children, and others let the children be as big as they want and try to space them out in different ways.

If you want to explore these types yourself, I have the project on GitHub.


Catch up on my other posts in this series:


The post Exploring UIStackView Distribution Types appeared first on Atomic Spin.

How to Pick Your Battles on a Software Team

Creating software is an emotional process for the team members who all want to see it succeed, and this can create tension. The phrase “you have to pick and choose your battles” is commonly used. But, how do you make those decisions?

Pick Your Battles Software

Winning and Losing Scenarios

When a team is working together, but they are “battling” one another, I like to define “winning” a battle as effectively persuading the other party that your idea will make the software product better. Conversely, there are several different conditions that constitute “losing.” The team can lose if you make a teammate feel like their contributions aren’t valuable. The product itself can also lose by missing out on early critique of its features, or by missing an opportunity to have its features developed less expensively.

A winning scenario:

In a planning meeting, a developer points out that there’s a pre-built charting tool that can do most of the chart’s required features quickly, and the product team says they’re willing to compromise on how the chart labels appear.

A losing scenario:

In a code review, the reviewer pressures the coder to make changes that make a big performance improvement, but the reviewer doesn’t explain to the coder the benefit of making the change, and the coder resents the reviewer for making them do the extra work.

When picking a battle, ask yourself a few questions.

Can you win?

If you’re going up against a set direction of the product that’s already been hashed out, and you’ve already raised your concern, maybe it’s time to step back. You probably can’t win.

If you’re a technical leader on the project ramping someone in and they’ve opened a code review that doesn’t follow the standards you’ve set for the project, step forward—but carefully. A conversation is going to be much more effective than tearing apart their code review line by line.

Is it worth it?

How severe is the issue to your product? If you want to push back against the business requirements to get the feature done in a more timely manner, take a moment to think about how much time you’re saving. If it’s less than a few hours (and within the estimated complexity), the business requirements aren’t worth changing. If it could save a week of work, though, it’s definitely an option worth bringing to the table.

Imagine in a code review, another developer opens a good PR, but it’s stylistically different from the way you would do it.

Ask yourself:

  • Is your feedback specifically identified as the best practice for your codebase?
  • Is there a non-trivial performance reason to change up the approach?
  • Is the code’s readability a problem?

If none of the above is true, it might be better to let it go. This lets the other developer feel a deserved sense of pride about the good code work they completed.

What is the noticeable gain of raising the stakes and challenging someone else’s approach?

In every good battle, the participants fight for something bigger than themselves. While it may not be as epic as a war movie, your reasons for engaging your teammates should also be worthwhile.

When challenging the business side of your project, your goal should be to add value to the product’s reliability and viability.

When challenging other developers, your goal should be to improve the quality of the code that your team is creating, so that the product will be more stable and maintainable.

Choosing Losing Battles

With those questions in mind for picking battles that you can and should win, sometimes starting a losing battle is also important. A losing battle can be a step toward broadening a team’s shared understanding of something that needs improvement.

A losing battle with the product team might be proposing an alternative to a UI you think is difficult to use. Your alternative may not be accepted as the path forward, but on the journey toward realizing that, your team might express interest in doing some user testing to get concrete design feedback and improve the usability of the product going forward.

A losing battle with another developer often manifests itself as a learning opportunity for both parties. Your code may not be as efficient or effective as you thought it was. In some situations, the discussion and research may lead to an even better third option.

Hard-lost Battles

We’ve all seen battles that haven’t gone well. Usually, that happens when someone makes it personal with some variant of “I don’t like your code/design/approach.”

It may have even been you, especially if you were caught on a day that wasn’t your best. We all do it. Just step away when you realize what’s happened, and then come back later with an in-person conversation and try to smooth it over.

If someone else made it personal against you, the best thing you can do is take the time to be angry. Later, when you’re calm, engage them in a personal conversation, and respond to any concerns objectively.

Developing Your Battle Skills

Not every battle is going to be a winning one, and understanding when to challenge a teammate and when to hold back is a skill that can only be developed with practice. The battles I’ve lost by not being prepared, the battles I’ve lost by picking on something trivial, and the battles I should have started—but didn’t—are what inspired this blog post.

The more stressful a situation is, the more I find pragmatism is the best tool for improving the product and the team. What are your strategies for choosing when to push back and when to let it be?

The post How to Pick Your Battles on a Software Team appeared first on Atomic Spin.

Send HTML Elements to Another DOMension with Ember Wormhole

I recently solved an old layout problem with a new tool. In this post, I’ll tell you about a challenge my team faced when placing dropdown menus in certain areas of an Ember app and how we used Ember Wormhole to tackle it.

A Simple Component

Say you’re building a reusable UI widget. It’s a little card, and on that card is a dropdown menu:

dropdown

(In this case, the widget is an Ember.js component, and the dropdown menu is provided by Foundation 5.)

The menu is populated dynamically with information known inside the component, so we naturally placed it right in the component’s template:


<div class="card-thing">
  <div class="name" >{{name}}</div>
  <div class="menu-button" data-dropdown="drop1-{{elementId}}" aria-controls="drop1-{{elementId}}" aria-expanded="false">⚙</div>
  <ul id="drop1-{{elementId}}" class="f-dropdown" data-dropdown-content aria-hidden="true" tabindex="-1">
    <li><a href="#">This is a link</a></li>
    <li><a href="#">This is another</a></li>
    <li><a href="#">Yet another</a></li>
  </ul>
</div>

The dropdown menu is absolutely positioned. Foundation styles the element directly; the <ul> looks like this when it’s open:


<ul class="f-dropdown open f-open-dropdown" 
    data-dropdown-content="" 
    aria-hidden="false" 
    tabindex="-1" 
    id="drop1-ember386" 
    style="position: absolute; left: -4.39062px; top: 158px;">

Misbehavior Deep Inside the UI

Imagine that you’re rendering a few components deep inside some overflow:scroll containers. Maybe there’s a responsive grid of cards inside a collapsible drawer, which is inside another collapsible drawer. But I digress; here’s a simplified version of what can happen:

yuck

The component is effectively larger when the menu is open. The size of the scrollable region outgrows its viewport, and we get a scrollbar. Yuck.

The Problem at Hand

In short, I’m trying to reconcile two conflicting requirements about where the dropdown should go.

  1. CSS leads me to place the absolutely-positioned element outside the overflow:scroll container. We don’t want the menu to affect the component’s geometry.
  2. The hierarchy of the UI leads me to implement the dropdown menu inside the card component, deep inside the overflow:scroll container(s). That’s where the information used to populate the menu is available, and where its actions are handled. Even if information flow didn’t require this placement, I’d still want to keep logical proximity between these related concerns and to abstract the menu details away from users of the card component.

Is there some way we can have both?

Into the Wormhole

Yapplabs’ Ember Wormhole provides a generalized solution to this kind of problem. It’s a component that renders its contents elsewhere on the page while preserving Ember data binding, action bubbling, etc. It’s also really simple to use:


{{#ember-wormhole to="another-dimension" menuClicked="menuClicked"}}
  <ul id="drop1-{{elementId}}" class="f-dropdown" data-dropdown-content aria-hidden="true" tabindex="-1">
    {{#each menuOptions as |option|}}
      <li><a href="#" {{action "menuClicked" option}}>{{option}}</a></li>
    {{/each}}
  </ul>
{{/ember-wormhole}}

Specify the other end of the wormhole with something like this:
<div id="another-dimension"></div>, and voila!

Conclusion

Here’s how it looks in action. Notice that the menu <ul> is rendered outside the card’s DOM.

wormholing

The sample project used in this post is available on GitHub.

I first learned of Ember Wormhole via ember-modal-dialog, which I also heartily recommend.

The web development ecosystem has evolved gradually over time. Nobody saw web components coming when overflow:scroll was specified in 1998. Piling technologies on top of technologies can seem a little crazy, but today, I’m glad I found this one.

The post Send HTML Elements to Another DOMension with Ember Wormhole appeared first on Atomic Spin.

Atomic Onboarding – What Works in 9 Guidelines

We care deeply about our onboarding process at Atomic. We recognize that work relationships are human relationships and that it’s crucial to demonstrate respect for our new employees, show that we really value them, and that we’re excited to have them joining us. We want to do everything we can to set them up for success.

Our onboarding process gives us a chance to welcome new Atoms and provide a practical demonstration of our company values. It makes the difference between an energizing and highly productive first year at Atomic and a potentially stressful one. Investing in our onboarding process makes very good business sense, as it increases retention and decreases time-to-productivity for new Atoms.

We’re very excited to have six new Atoms join us in Grand Rapids this summer. Their arrival has given us the opportunity to revisit our onboarding guidelines and update them with the best practices we’ve put together over the years. We’ve received great feedback on our onboarding process from our newest Atoms, so I wanted to share our latest nine guidelines.

Onboarding new employees at Atomic

1. Start the onboarding process well before an Atom’s first day.

New Atoms feel most comfortable if they know what to expect during their first day and their first week. They have a better experience if they know some people coming in and feel like they already have allies on their first day.

Tips

  • Send a welcome letter when the new Atom accepts an offer.
  • Invite new Atoms to social events prior to starting.
  • Several days prior to their start date, send a detailed agenda for their first day and their first week at Atomic.
  • Provide answers to common questions prior to their arrival.
  • Make sure they know when they’re expected to show up, where to park, and what to do when they walk into the building on their first day.

2. Make it clear that we’ve been looking forward to their arrival.

It’s important for new Atoms to see we’ve been planning for their arrival, and we are excited to welcome them. There should be clear evidence we’ve prepared a place for them.

Tips

  • Ensure that the new Atoms’ team will be in the office and ready to greet them.
  • Have a workstation ready for the new Atom with a display, keyboard, and a decent chair.
  • Set up the Atom with a laptop and any other tools needed to perform the job.
  • Make sure all necessary accounts have been created and that all HR paperwork is ready to go.
  • Ensure that new Atoms have everything necessary to gain access to the building.
  • Order business cards, so they’re ready on the first day.
  • Put together a welcome gift and have it waiting—maybe a nice snack and some flowers.

3. Make the first day special.

Think long-term on an Atom’s first day. It should be spent getting to know folks, asking questions, and settling in.

Tips

  • Spend time welcoming the new Atom. Take at least 30 minutes to chat before kicking into any planned material.
  • Make sure new Atoms get a full tour of the office early on. They need to know where the restrooms are, where the snacks are, and where to get a drink.
  • Take breaks during the day. Grab a coffee at the neighborhood cafe, go to the store, or walk around the block.
  • Organize lunch for the new Atom with a couple of colleagues (don’t go yourself—use this break to catch up on email and Slack).
  • Focus on getting them socially connected for the rest of the week. Don’t drown them in paperwork or details.
  • Don’t throw the new Atom into project work on the first day; there will be plenty of time for that later.

4. Map out the first few months.

People will have a much more comfortable start to their Atomic careers if they have a roadmap to follow.

Tips

  • Let them know what to expect in terms of onboarding sessions and information.
  • Give a detailed overview of the project(s) they’ll be working on.
  • Explain the expectations we’ll have for them and how those will ramp up over the first weeks and months.
  • Explain how they’ll be evaluated and when they should expect feedback.

5. Remember that onboarding is a process—not an event.

While we want Atoms to have a wonderful first day, it’s important to understand that getting them fully integrated is an ongoing process.

Tips

  • Establish a culture pair on the first day. It’s important to have someone who is deeply familiar with Atomic’s culture readily available to answer questions throughout a new Atom’s first few months.
  • Check in regularly over the first months to ensure questions are answered and the Atom has everything they need.
  • Make it very clear that you are available and willing to solve problems for them.
  • Give special attention to new Atoms for months, not just during their first week.

6. Provide feedback.

Integrating into a new organization is stressful—it’s hard to know exactly how you’re doing and what people are thinking of you. Ease this stress by providing regular feedback. Have conversations early and often about areas that need improvement.

Tips

  • Find areas to give positive feedback early. Comment on their good work regularly during the first few weeks.
  • Create a regular schedule for formal feedback, and clearly communicate this schedule to new Atoms. They should get regular updates and know when to expect them.
    • All new employees should get regular feedback during their first three months.
    • The current recommendation is to schedule 15-minute weekly feedback sessions starting during the employee’s second week.
    • If new Atoms are doing great and the sessions no longer seem productive, congratulate them for doing a great job, and end the sessions early.
  • Recognize that you do a disservice to new Atoms if you hold back pointers that could help them early on.
  • Pair with another Atom to polish message and tone before presenting areas for improvement.

7. Provide access to leadership.

Atoms feel most comfortable when they have strong social connections within the company. Relationships with leadership can be difficult to establish—access is limited, and it’s intimidating to ask. We should do everything possible to help new Atoms develop these relationships.

Tips

  • Schedule a roadtrip with our CEO as early as possible.
  • Schedule pair lunches for new employees with managing partners and senior Atoms.
  • Pull new folks into conversations with leadership at group events.

8. Create social connections.

Social connections are key to new Atoms feeling safe and part of the team. We need to foster these relationships; this should be an intentional part of the onboarding process.

Tips

  • Be sure new Atoms are properly introduced to the company (all offices!).
  • Connect new Atoms with a peer group.
  • Make sure Atoms on other teams are engaging with the new employee.
  • Encourage Atoms to take new employees out for lunch—track this, and reach out to individuals if a new Atom doesn’t have a healthy pair lunch schedule.
  • Allow new Atoms to participate in cross-team efforts (hiring, recruiting, workshops).

9. Gather feedback.

It’s challenging to see the onboarding experience from a new Atom’s perspective. We need to gather feedback during the first few months to see how effective our process is. We should do this after the first week, first month, and at three months.

Tips

  • Use a standard template for feedback.
  • Record responses, so we have data to analyze as we experiment with new approaches.
  • Update any relevant docs with lessons learned.

Wrapping Up

I hope you find these tips useful! I expect you’ll see great returns when you provide new folks with an intentional and welcoming experience.

The post Atomic Onboarding – What Works in 9 Guidelines appeared first on Atomic Spin.

How to Vertically Middle-Align Floated Elements with Flexbox

I recently discovered a very simple Flexbox-based solution to a problem that has given web designers and developers issues for years.

Consider the following situation:

  1. You’re working with a grid framework that uses floats to create columns. Think Bootstrap, Foundation, Skeleton, Susy, or any number of others.
  2. You have two columns of dynamic content adjacent to each other, and you don’t know the size of the column content or which column will be taller.
  3. You need to vertically middle-align the two columns.

Our desired layout would look like this:

desired-outcome

But by default, the two columns will top-align themselves within the container like this:

default-behavior

So, how can we get our columns to middle-align without breaking our float-based layout? Up until recently, this seemingly simple problem has been surprisingly difficult to solve.

Can’t I just use ‘vertical-align: middle’?

Unfortunately, no, for a couple of different reasons.

First, as the CSS docs state, “The vertical-align CSS property specifies the vertical alignment of an inline or table-cell box.” Our elements are not inline, inline-block, or table-cells, so this rule won’t work without altering our display styles.

Second, our grid framework uses ‘float: right’ to position our two column elements. The CSS rules state, “A floating box must be placed as high as possible.” This means that a floated element will always be top-aligned.

While the first issue can be solved by changing the ‘display’ rule to make the columns ‘inline-block’ or ‘table-cell’, there is no CSS technique that solves the second issue. We would need to remove the float rules, which would interfere with the underlying grid framework.

Flexbox to the Rescue

As usual, Flexbox has a simple fix for our problem. Here it is in two easy steps:

  1. Add ‘display: flex’ to our container element.
  2. Add ‘align-items: center’ to our container element.

That’s it! Here’s what the HTML and CSS might look like for our simplified example:

1
2
3
4
<div class="container">
 <div class="column-1">[Dynamic content]</div>
 <div class="column-2">[Dynamic content]</div>
</div>
.container {
  display: flex;
  align-items: center;
}
.column-1,
.column-2 {
  float: left;
  width: 50%;
}

As you can see in the animation below, the columns remain middle-aligned regardless of the size of their content:

flexbox-animation

What makes this solution especially nice is that adding these two rules to our container element solves the alignment problem without altering the styling of the columns in any way. Modern browsers can take advantage of the Flexbox styling, while older browsers just ignore it, leaving the two columns top-aligned.

You can see the final solution in action in this Codepen I created.

The post How to Vertically Middle-Align Floated Elements with Flexbox appeared first on Atomic Spin.

Writing a Fuzzing API with Clojure’s test.check

I’ve written before about testing CSS using a fuzzing API. Having relied on my fake, random API over the last several months, I’m confident that it’s a tool I’ll use on all my future projects. Besides supplying the app with random data, it’s also given me an unprecedented ability to customize the fake API’s behavior and test unusual and hard-to-reproduce scenarios. In this post, I’ll walk you through the key components of my API and some ways that I’ve used it.

I wrote my fuzzing API in Clojure. Clojure provides two essential capabilities: a REPL and the test.check library.

Create a Server

We’ll use Ring to create a simple HTTP server.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
(ns fuzz-api.core
  (:require [ring.adapter.jetty :refer [run-jetty]]
            [ring.middleware.reload :refer [wrap-reload]]
            [ring.middleware.stacktrace :refer [wrap-stacktrace]]))
 
(defn item [req]
  {})
 
(defn items [req]
  {})
 
(defn handler [req]
  (let [f (condp re-matches (req :uri)
            #"^/api/items/d+$" item
            #"^/api/items$" items
            (fn [_] {:status 404}))]
    (f req)))
 
(def app
  (-&gt; handler
    wrap-reload
    wrap-stacktrace))
 
(defonce server
  (run-jetty #'app {:port 5003 :join? false}))

Starting a REPL with lein repl, the following will start the server:

1
user=&gt; (require 'fuzz-api.core)

The server will now respond to requests on Port 5003, but it only gives empty responses. We’ll use Cheshire‘s cheshire.core/generate-string function to serialize Clojure data structures as JSON.

1
2
3
4
5
(defn item [req]
  {:body (generate-string {:id 5})})
 
(defn items [req]
  {:body (generate-string {:items [{:id 5}]})})

Generate Fake Data

To get random data, we’ll compose some test.check generators together. Require test.check’s generators under the alias gen inside the namespace’s :require block:

1
[clojure.test.check.generators :as gen]

Here’s a generator to create random IDs:

1
(def ids (gen/choose 0 1000000))

Generators are special test.check objects instead of normal values. To get a primitive value, use gen/generate:

1
2
(defn item [req]
  {:body (generate-string {:id (gen/generate ids)})})

Now every time we call /api/items/4, we’ll get an item with a random ID between 0 and 1,000,000.

To generate a list of items, we’ll want something that can generate whole items, not just IDs.

1
2
3
4
5
(def random-items
  (gen/fmap
    (fn [id]
      {:id id})
    ids))

gen/fmap takes a function and a generator. It passes values from the generator into the function and returns a new generator of the results. We can use random-items in our item function in place of creating a map:

1
2
(defn item [req]
  {:body (generate-string (gen/generate random-items))})

We can use random-items to create a list of items:

1
2
3
(defn items [req]
  {:body (generate-string
           (gen/generate (gen/vector random-items 20)))})

Our list of items isn’t fully random. It always returns 20 items. Let’s get lists of random lengths, too:

1
2
3
4
5
(defn random-list [generator]
  (gen/bind
    (gen/choose 0 50)
    (fn [n]
      (gen/vector generator n))))

Notice that we used gen/bind instead of gen/fmap. gen/fmap takes values from a generator and produces a new value (which then gets turned into a generator). gen/bind takes values from a generator and produces a new generator.

In this case, we’ll use gen/choose again to randomly pick a number between 0 and 50, then pass it to our function to create a generator of vectors with the chosen length.

Our random-list function is also an example of a higher-order generator, a generator that takes another generator as an argument.

Here’s how we use it:

1
2
3
(defn items [req]
  {:body (generate-string
           (gen/generate (random-list random-items)))})

That’s a very brief introduction to using test.check’s data generators. You can find more information in its docs.

Manipulate the Server

One of the chief pleasures of creating our server with Clojure is that we can change its behavior it at runtime. Because we started it from the REPL, we have access to the running instance and its code.

Let’s suppose that we want to see what happens in our app when it gets a response of 401 Unauthorized from the /api/items endpoint.

From the REPL, re-require our namespace to get all the changes we’ve made:

1
user=&gt; (require 'fuzz-api.core :reload)

Replace the items functions with one that returns a 401:

1
2
user=&gt; (alter-var-root #'fuzz-api.core/items
  #_=&gt;   (fn [_] (fn [req] {:status 401})))

When you make an HTTP call to /api/items, it should now return a status of 401 Unauthorized.

To reset the server to its original state, reload the namespace again.

Experiment!

There’s a lot more that you can do with a random, REPL-driven API. You can delay server responses to see loading animations. You can make responses include certain text to see how search results are highlighted. You can freeze responses so they return exactly the same thing they did last. You can make them return in different amounts of time to test for race conditions. You can forward requests to another API. The tutorial above is just a taste.

The complete example code for this post is on GitHub.

The post Writing a Fuzzing API with Clojure’s test.check appeared first on Atomic Spin.