How do you guys set up naked domains in Heroku apps?

Let's say:

I have mydomain.mx and I want to allow anybody to type in the browser

www.mydomain.mx
# or
mydomain.mx
# or
http://mydomain.mx
# or
http://www.mydomain.mx

And to resolve/redirect to the secure version of it -> https://mydomain.mx (non www)

It is basically done, following this approach:

  1. You need to go to the settings section in Heroku.com and enabling the SSL option(only available in hobby and paid plans)
  2. Add your domain with two variations inside the settings section within heroku.com

  3. Create those two CNAMEs entries in your DNS providers (I'm using cloudfare.com for free)

  4. Create a redirect rule in your application(this depend on the technology and language you are using), in my case, as I'm using Rails, so it was a matter of adding this to the top of the config/routes.rb file:

  match '(*any)',
    to: redirect(subdomain: ''),
    via: :all,
    constraints: { subdomain: 'www' }

There you go! you are ready to go, here is a live example (Site in construction as of November 26th, 2021)

www.valoralo.mx
http://valoralo.mx
http://www.valoralo.mx
valoralo.mx

All of them will resolve to the same domain: https://valoralo.mx

Spaceship Operator <=>

The spaceship operator compares two objects (from left to right), returning either -1, 0, or 1.

Explanation

a <=> b

return -1 if a < b
return 0 if a == b
return 1 if a > b
4 <=> 7 # -1
7 <=> 7 # 0
7 <=> 4 # 1

Example one

As you know, in ruby (as in any language) we can get a result in different ways, we could use just the sort method, of course, but I just wanted to put this in another way:

languages = ['ruby', 'go', 'javascript', 'phyton', 'rust', 'elixir']

languages.sort{|first, second| first <=> second } # ["elixir", "go", "javascript", "phyton", "ruby", "rust"]

languages.sort{|first, second| second <=> first } # ["rust", "ruby", "phyton", "javascript", "go", "elixir"]

Example two

Suppose that we have the next array with the numbers 1 to 10, and we will like to separate them into different groups: 1. One group for the numbers that are less than 5 2. Another group with the number 5 3. The last group with the numbers that are greater than 5

We could get this result by iterating the array and then by putting a couple of if statements in order to group these 3 categories, but with the spaceship operation we could get this result in an easier way:

numbers = Array(1..10)
target = 5

numbers.group_by{ |number| number <=> target } # {-1=>[1, 2, 3, 4], 0=>[5], 1=>[6, 7, 8, 9, 10]}

Sort an array of objects by a property value

Imagine that we have the next object:

const names = [
  { name: 'Sam', lastName: 'Belmor'},
  { name: 'Yasser', lastName: 'Velasco' },
  { name: 'Ayrton', lastName: 'Morales' }
]

If we wanna sort those values alpabethically by name we could do this:

names.sort((a, b) => (a.name > b.name) ? 1 : -1)

We'll have this result:

[
  { name: 'Ayrton', lastName: 'Morales' },
  { name: 'Sam', lastName: 'Belmor' },
  { name: 'Yasser', lastName: 'Velasco' }
]

If return 1, the function communicates to sort() that the object b takes precedence in sorting over the object a. Returning -1 would do the opposite.

Use 'super' and add custom arguments to a specific class

Sometimes we want to create a parent class that will be shared for children classes, nevertheless, in some of the children classes we need additional arguments that will be only specific for that class and we don't need them in the parent class, to avoid adding additional arguments that won't be relevant to the parent class, we can do the next:

class ParentClass
  attr_reader :user

  def initialize(user)
    @user = user
  end
end
class ChildOne < ParentClass
  attr_reader :token

  def initialize(user, token)
    super(user)
    @token = token
  end
end

This way the new variable token will be available only for the ChildOne class.

Constant resolution operator `::`

Also, known as scope resolution operator.

When we work with namespace it's very common to override some objects, etc that we already have. This could cause us headaches when we try to access a specific object and that object has the same name as our namespace. To have a clearer idea, let's review the next example, imagine that we have the next nested modules:

module FHIR
  module Services
    module Appointment
      def appointment
        @appointment ||= Appointment.find(id)
      end
    end
  end
end

If you do Appointment.find(id) you will get an error similar to this: NoMethodError: undefined method 'find' for FHIR::Services::Appointment:Module.

That ^ is because the Appointment is doing reference to the namespace FHIR::Services::Appointment (local scope) instead of the Appointment model (global scope).

The constant resolution operator will help us to resolve this. If you put:

::Appointment.find(id)

This will work because is referencing the global namespace which is the Appointment model this way you can access directly to the model instead of the current namespace.

'fixup' and 'rebase' for neat commits

Description

Sometimes we are working on a branch and we want a specific change in a specific commit that is not the last one, we could use fixup to have our commits neat and to avoid doing a disaster with them.

Example

Imagine that we have a commit story like this:

commit 30e9b16e098315e459f46313c099317ab74decbd
Author: Sam Belmor <sambelmor@gmail.com>
Date:  Tue Sep 28 18:57:32 2021 -0500

  Add the MVC architecture

commit e13f8600584a8b304c25d08bbaa13d1999f51569
Author: Sam Belmor <sambelmor@gmail.com>
Date:   Tue Sep 28 18:51:06 2021 -0500

  Add koa/node setup

commit b4b7ee003d554fa7eaa967bcf236c9a02c5a7249
Author: Yasser Batas <yassk8@gmail.com>
Date:   Thu Jul 15 07:11:39 2021 -0500

  Initial commit

If we do some changes related to the koa/node setup and we want those changes in the second commit e13f8600584a8b304c25d08bbaa13d1999f51569, to avoid doing another commit we could do the following:

1. Add your changes

git add .

2. Copy the commit key where you want your changes

For this example we want the changes in the commit Add koa/node setup with the key e13f8600584a8b304c25d08bbaa13d1999f51569.

git commit --fixup e13f8600584a8b304c25d08bbaa13d1999f51569

3. At this point your changes were added, if you put:

git log

You will see something like this:

commit 3ef0a9c5a3a67b5dff7a7f6374921babf7a40c12 (HEAD -> feature/#2-knex-setup)
Author: Sam Belmor <sambelmor@gmail.com>
Date:   Thu Oct 21 11:50:35 2021 -0500

  fixup! Add koa/node setup

commit 30e9b16e098315e459f46313c099317ab74decbd
Author: Sam Belmor <sambelmor@gmail.com>
Date:  Tue Sep 28 18:57:32 2021 -0500

  Add the MVC architecture

commit e13f8600584a8b304c25d08bbaa13d1999f51569
Author: Sam Belmor <sambelmor@gmail.com>
Date:   Tue Sep 28 18:51:06 2021 -0500

  Add koa/node setup

commit b4b7ee003d554fa7eaa967bcf236c9a02c5a7249
Author: Yasser Batas <yassk8@gmail.com>
Date:   Thu Jul 15 07:11:39 2021 -0500

  Initial commit

As you can see a new commit was added, with the difference that you'll see the fixup! word before the commit's description

fixup! Add koa/node setup

At this point, you should check if this is the commit where you want your changes. If this is correct go-ahead to the next point if you made a mistake you could do:

git reset HEAD~

And start again. Be sure to copy the correct commit's key.

4. Use squash to join your commits

Now you're ready to squash your new changes with your old commit. 1. First, you need to copy the previous commit's key from the one that I want to do the squash. For this example the key that I need is this key b4b7ee003d554fa7eaa967bcf236c9a02c5a7249 from this commit Initial commit 2. So you should put the following:

git rebase -i --autosquash b4b7ee003d554fa7eaa967bcf236c9a02c5a7249

5. Confirm your changes

When you do the previous command a text editor will open (nano, vim, etc), and you will see something like this:

pick e13f860 Add koa/node setup
fixup 3ef0a9c fixup! Add koa/node setup
pick 30e9b16 Add the MVC architecture

When you close that window, your changes will be saved and now you'll have the new changes in the corresponding commit.

Separate health check endpoint using puma

Puma offers a way to query its internal stats by enabling a controll app in a separate port, this can be useful when we need to know if the app is alive, this is different than normal health check endpoints because it does not get processed by rails at all.

To enable this functionality, all you need to do is to add this line in your puma.rb file:

activate_control_app 'tcp://0.0.0.0:9293', { no_token: true }

It will start a second web server in the port 9293 that can be queried by monitoring tools or even balancer healthcheck.

ecruz@Edwins-MBP % curl 'http://127.0.0.1:9293/stats'
{"started_at":"2021-10-15T21:39:55Z","workers":2,"phase":0,"booted_workers":2,"old_workers":0,"worker_status":[{"started_at":"2021-10-15T21:39:55Z","pid":44969,"index":0,"phase":0,"booted":true,"last_checkin":"2021-10-15T21:40:05Z","last_status":{"backlog":0,"running":5,"pool_capacity":5,"max_threads":5,"requests_count":0}},{"started_at":"2021-10-15T21:39:55Z","pid":44970,"index":1,"phase":0,"booted":true,"last_checkin":"2021-10-15T21:40:05Z","last_status":{"backlog":0,"running":5,"pool_capacity":5,"max_threads":5,"requests_count":0}}]}%
ecruz@Edwins-MBP %

Check the documentation for more options/usages

Numberic separators JavaScript

Numberic separators is a new JavaScript feature that allows you to use underscores as separators to help to improve readability using a visual separation between groups of digits.

// A billion
const amount = 1_000_000_000;

// Hundreds of millions     
const amount = 1_475_938.38;

// 6234500 cents (62345 dollars)
const amount = 62345_00;

// 1,734,500
const amount = 1_734_500; 

// 20^30000
const amount = 2e30_000;

Javascript event loop

The event loop is the secret behind JavaScript's asynchronous programming. JS executes all operations on a single thread, but using a few smart data structures, it gives us the illusion of multi-threading but first we have to understand the Call Stack.

Call Stack

The call stack works based on the LIFO principle(last in first out) When you execute a script, the JavaScript engine creates a Global Execution Context and pushes it on top of the call stack.

function multiply(a, b) {
    return a * b
}

function squere(n) {
    return multiply(n, n)
}

function printSquere(n) {
    var result = squere(n)
    console.log(result)
}

printSquere(4)

**Stack**
4- multiply
3- squere
2- printSquere
1- main

Result: 16

Call Stack with async callbacks (Even loop)

The event loop facilitates this process; it constantly checks whether or not the call stack is empty. If it is empty, new functions are added from the event queue. If it is not, then the current function call is processed.

An example of this is the setTimeout method. When a setTimeout operation is processed in the stack, it is sent to the corresponding API which waits till the specified time to send this operation back in for processing.

console.log('hi')

setTimeout(()=> {
  console.log('there')
},5000)

console.log('bye')

**Stack**
3- there
2- bye
1- hi

**webapis**
setTimeout callback(cb)

**taskqueue**
callback(cb)

**evenloop**
move cb to stack

In the example the setTimeout Callback enters the webapi stack executes and then goes to the task queue and waits for the stack to become empty and the event loop moves the callback to the stack.

module_function

What it does?

  • module_function allows exposing instance’s methods so they can be called as they would be class methods.
module User
  def name
    'Hello Sam'
  end
end

If you try to do this:

user = User.new
user.name

You're gonna receive an error because modules do not respond to the new method.

How can we use it?

You can use this useful method module_function:

module User
  module_function

  def name
    'Hello Sam'
  end
end

And call the name method like User.name

  1. Use module_function to use all the methods inside a module as class methods or
  2. Use module_function :name to only apply it in a specific method

A second option to do it

Another option to do so is using extend self instead:

module User
  extend self

  def name
    'Hello Sam'
  end
end

Underscores are not allowed as part of domain names

According to rfc1035, underscores (_) are not allowed as part of domain names.

The labels must follow the rules for ARPANET host names. They must start with a letter, end with a letter or digit, and have as interior characters only letters, digits, and hyphen (-). There are also some restrictions on the length. Labels must be 63 characters or less.

This means domain names like my_domain.com or sub_domain.main-domain.com are invalid.

Special thanks to @jclopezdev for finding this out.

JavaScript null vs undefined

In JavaScript null and undefined are rather strange values, both serve a very similar purpose, which is to indicate the absence of a value.

Null

Null is used to assign a reference to an object that you will no longer need or, directly, you want to have the variable declared but initialize it with a value that you still do not know what it will be exactly. In all these cases the best thing to do is to assign a null value.

  var miVariable = null;
  console.log(miVariable);

//log null

undefined

For undefined means that the variable is declared but its value has not yet been defined.

  var miVariable
  console.log(miVariable);

//log null

Both values are values of type false, so if you do a non-strict comparison you will get true undefined, which means that the variable is declared but its value has not yet been defined.

if (null == undefined) {
  return true
 }
//log true

and if you do a strict comparison, because they are not really the same, it returns a false:

if (null === undefined) {
   return true
 }
return false
//log false

Javascript Hoisting

This means that variable and function declarations are physically moved to the beginning of the code and are allocated in memory during the compilation phase.

function welcomeTo(name) {
  console.log("Welcome to " + name);
}

welcomeTo("Magmalabs");
//returns welcome to magmalabs

As you can see hoisting allows you to use a function before declaring it in the code.

welcomeTo("Magmalabs");

function welcomeTo(name) {
  console.log("Welcome to " + name);
}
//returns welcome to magmalabs

And also allows you to use a function after declaring it in the code.

For variables, hoisting only applies to the declaration, not to their assignment. example:

We declare the variable name but we got an undefined

console.log(name); 
var name = magmalabs;
//return undefined

That’s because JavaScript only hoist the declaration

var name;

console.log(name); 
name = magmalabs;
//return undefined

To avoid these errors, it is very important to keep in mind that hoisting only applies to the declaration.