jQuery: How to attach an event handler only once

With "attaching an event handler once" you possibly mean one of these two things:

Register a function for an event, and discard it once that event has happened

Use one instead of on.

$(element).one('eventName', function() { ... });

It has the same API has on.

When code is run multiple times that registers a function for an event, do that only once

With jQuery, you can de-register callbacks. You can use that to achieve registering a function only once.

function myAction() { ... }; // defined somewhere globally o...

Ruby: control flow with throw and catch

This article will show you how to use throw and catch. It's a nice tool to break out of multiple loops when a result is obtained.

Also see our card Ruby: A small summary of what return, break and next means for blocks.

Form letters with LibreOffice Writer

This is painful. Consider using Microsoft Office or switching careers. If you need to write < 20 letters consider doing it manually.

So you didn't listen and here it comes:

  1. Ignore the Mail Merge Wizard. It will crash or destroy your document.
  2. Export your addresses, recipient names, etc. as a .ods spreadsheet (.xls, .xlsx, .ods). Use any columns that work for you, but be consistent. I like to use one column for the address, one column for the salutation line.
  3. Import the spreadsheet as an address book source: *Tools => Add...

Error during Rails 5 upgrade: Environment data not found in the schema

This error is raised because your old database does not have a configured environment yet, which Rails 5 enforces.

If this error occurs while migrating your parallel test databases, make sure to update the parallel_tests gem first: current versions fix this. If you're still using Cucumber < v3, the latest version of parallel_tests will be 2.18.0.

Remember: LoDash syntax is a bit different from UnderscoreJS

Since we are using LoDash instead of UnderscoreJS in recent/current projects, you should keep in mind that their syntax is a bit different.

UnderscoreJS

In UnderscoreJS, methods always return a value:

x = [1, 2, 2]
_.uniq(x) // => [1, 2]
_(x).uniq() // => [1, 2]

If you want to chain multiple calls, you need to start off with a _.chain, and call value() to terminate the chain.

_.chain(x).uniq().map(function(i) { return i + 10 }).reverse().value() // => [12, 11]

##...

How to find and replace empty cells in Libre Office Calc

To find and replace (CTRL + H) empty cells in Libre Office Calc you can use a regular expressions (also called "Finds an empty paragraph" in context of a spreadsheet):

Screenshot_2017-12-04_11-07-04.png

It is also possible to just enter a regular expression in the search (CTRL + F), but there is no option to only search in the current selection like in the screenshot above. Use find and replace instead if needed.

How to use cookies with curl

When making requests using curl, no cookies are sent or stored by default.
However, you can tell curl to re-use cookies received earlier (or forge your own cookies).

There are 2 command line switches you need to use:

  • -c will write cookies to a given file
  • -b will read cookies from a given file

Example

The remote server sets a "foo" cookie to value "bar". We tell curl to store them to a file at /tmp/cookies using the -c switch.

$ curl -c /tmp/cookies http://httpbin.org/cookies/set?foo=bar

You may look at the file, ...

Rails: Migration helper for inserting records without using models

You should avoid using application models in your migrations. But how else could you create records in a migration?

The most basic way is to write plain SQL, but since INSERT statements are no pleasant write for Rubyists, here is a simple wrapper:

Record creation helper for migrations

The helper method below takes a table name and a hash of attributes, which it inserts into the specified table. Copy it over to your migration and profit!

  private

  def insert_record(table, **attributes)
    attributes.merge!...

CSS: Giving text lines a background-color (with configurable line padding and margin)

The gist is:

  • wrap the text with a span
  • use line-height for the spacing between lines ("margin")
  • use box-shadow to control the line background size ("padding")

Example

text_lines_with_background_color.png

span
  box-shadow: 0 0 0 10px #fff
  background-color: #fff
  box-decoration-break: clone # Fix Firefox
  line-height: 2.2

→ [jsfiddle](https://jsfiddle.net/2fmqgbh...

Jasmine: Expecting objects as method invocation arguments

To check if a method has been called in Jasmine, you first need to spy on it:

let spy = spyOn(window, 'alert')
codeThatAlerts()
expect(window.alert).toHaveBeenCalledWith('Important message')

To expect an object of a given type, pass the constructor function to jasmine.any():

expect(spy).toHaveBeenCalledWith(jasmine.any(Object))
expect(spy).toHaveBeenCalledWith(jasmine.any(String))
expect(spy).toHaveBeenCalledWith(jasmine.any(Number))

To expect an object with given key/value properties, use `jasmine.objectContaining(...

How to fix HTML elements being cut off when printing

When you print (or print preview) and elements are cut off (e.g. after 1st page, or "randomly") you should check your CSS rules for these:

  • Is there an element with "display: inline-block" that surrounds your content? Make sure it has "display: block" for printing.
    This primarily affects Firefox and Internet Explorer. Chrome seems to be able to handle inline-block elements in most cases.

  • Does the element itself, or a container, define "overflow: hidden"? Use "overflow: auto" (or maybe "overflow: visible") instead.

  • Is th...

Jasmine: Mocking API requests in an Angular service spec

Situation: You want to write a spec for a function inside an Angular service. This function at some point makes an API request and acts upon response. Notably, your Angular app employs uiRouter, although it is not used nor actually required for this test.

Working test setup

# Capitalized expressions are intended to be replaced with YOUR values

describe 'SERVICE', ->

  beforeEach ->
    module 'MODULE'

    module ($urlRouterProvider) ->
      # Prevent uiRouter's initialization, i.e. do not sync the current URL
      # with its r...

Limitations you should be aware of when Internet Explorer 9 parses CSS files

Internet Explorer until version 9 has some limitations when parsing CSS files

Summarized, these are:

  • Up to 31 CSS files or <style> tags per page.
  • Up to 4095 selectors per CSS file.
  • Up to 3 nested @import rules

To test the selector limit for a specific browser, check this CSS selector limitation test website.

When you run into this issue, the following links might be helpful to fix the problem. The Idea is to split up the css ...

HTTPie nice command line HTTP client

HTTPie consists of a single http command designed for painless debugging and interaction with HTTP servers, RESTful APIs, and web services

It easy to use and has very nice defaults and coloured output which makes it good for local testing.

Usage examples with curl equivalent:

# curl post
curl --data "foo=23&bar=42" https://example.org/blub
# httpie post
http https://example.org/blub foo=23 bar=42

# curl localhost
curl localhost:3000/users
# httpie localhost
http :3000/users

xlsxtream: Streaming & Fast XLSX Spreadsheet Writer for Ruby

When writing XLSX files, there are gems like rubyXL or axlsx. While they do offer features like formatting or graphs, to represent spreadsheet cells, they have to keep several Ruby objects in memory. When writing huge files, both will become slow and consume lots of memory.

Enter Xlsxtream, a Ruby XLSX library with less features (e.g. no individual cell styles) but which does away with the memory issue by streaming ...

PostgreSQL's OVERLAPS operator is not fully inclusive

PostgreSQL supports the SQL OVERLAPS operator. You can use it to test if two date ranges overlap:

=> SELECT ('2001-02-16'::date, '2001-12-21'::date) OVERLAPS
          ('2001-12-20'::date, '2002-10-30'::date);

overlaps
--------
true

An important caveat is that the date ranges are defined as start <= time < end. As such the later date is not included in the range:

=> SELECT ('2001-02-16'::date, '2001-12-21'::date) OVERLAPS
          ('2001-12-21'::date, '2002-10-30'::date);

overlaps
--------
false

Also compar...

chromedriver-helper gem in Gemfile might break you selenium tests (of other projects)

Summary: Don't add chromedriver-helper to the Gemfile

  • the executables might break your tests in projects where chromedriver-helper is not in the Gemfile
  • developers with different chrome versions will have problems using the same chromedriver-helper version

Background

If you install the chromedriver-helper gem, but don't have it in you Gemfile, your selenium tests might fail with:

Selenium::WebDriver::Error::WebDriverError: unable to connect to chromedriver 127.0.0.1:9515

The reason is that chromedriver-helper ov...

Inspecting Angular 1.x UI Router

If your Angular app has some decent complexity, it will not be easy to use UI Router straight away. Here are some hints on how to get around.

Accessing the UI Router $state service from the browser console

$state = angular.element(document.body).injector().get('$state'): Retrieves the Angular injector and asks it for the $state service.

Inspecting the current state

$state.current

Inspecting params of the current state

$state.params

Heads up: Angular may break links to the current URL (e.g. when using ngInclude)

Angular's location provider stalls links to the current URL, i.e. window.location. As soon as the $location service is activated in an Angular app, it will intercept links. The click event handler is registered in $LocationProvider.$get().

The motivation is reasonable, as they want to keep the Browser history clean when Angular is controlling it. However, when Angular is NOT controlling your interaction with the browser history (i.e. you're just using Angular as JS sugar on your page), Angular will create the above issue as soon as you u...

Git: creating and deleting a tag

Git has two kind of tags:

  • annotated
  • lightweight

Annotated tags are stored as full objects in the Git database. They’re checksummed; contain the tagger name, email, and date; have a tagging message; and can be signed and verified with GNU Privacy Guard (GPG)

The following command will create a (lightweight) tag:

git tag v0.1

An annotated tag is created by:

git tag -a v0.1 -m "a special tag message"

A normal git push will not push the tag. So in order to publish your (local) tags, you have to

git push --tags
`...

Turning off VCR when stubbing with Webmock

Sometimes when working with VCR you still want to use webmock. Since VCR hooks into webmock and fails when an unknown request is happening, you have to turn it off in order to use webmock like you are used to. Here is how to do this in rspec.

RSpec.configure do |config|
  config.around do | example |
    if example.metadata[:turn_off_vcr]
      VCR.turn_off!
      example.run
      VCR.turn_on!
    else
      example.run
    end
  end
end

Rails + Sidekiq::Web: Configuration for wildcard session cookies

When you're using Sidekiq::Web to monitor the Sidekiq status AND have your session cookie configured to a wildcard domain like .example.com, you need to take an additional step to keep your cookies valid.

Issue

Sidekiq::Web is mounted into your Rails application and will use the Rails session cookie for protection from CSRF attacs. While it somehow figures out the cookie name, it does NOT respect cookie configuration like a custo...

Webservice to test and inspect requests

Requestb.in is a webservice that gives you a temporary URL you can use to test request. The page will automatically record and display the latest web request made to it.