JavaScript dates

Every time I have anything to do with manipulating dates in JavaScript I need to stop and refresh my memory. Yes, there are amazing packages from Moment.js and Date-fns.

But why should I import a library just to a few simple things?

Here are my notes on dates (it is not an exhaustive list).

Time zones

There are 24 time zones mix in that many also have day light saving which adds/subtracts an hour. When a country does this is not constant around the world and is not fixed

So, in JavaScript there are two times:

  • Local = the time of the computer the code is running on
  • UTC = roughly the same as Greenwich Mean Time (GMT)

Date methods in JavaScript return Local time

In practice

Here I need to create a date range array. The range covers 30 days

const autoDays = () => {
      const daysInThePast = 30;
      const today = new Date();
      const pastDate = new Date(today);
      pastDate.setDate(today.getDate() - daysInThePast);
      return [
        pastDate.toISOString().substring(0, 10),
        today.toISOString().substring(0, 10)
      ];
    }

Explanation

  • Two ‘new Date()’ are used to avoid unwanted mutation
  • ‘today.getDate()’ returns the number part of the date. E.g. 29 in 29th July 2020
  • ‘pastDate.setDate(today.getDate() – daysInThePast)’ sets the date number. Notice how the number could be a negative or positive number. E.g. -10 or +36
  • JavaScript will correct the date to make sense. E.g. 36th July would become 5th August

Code rot and technical debt

I do not know why “technical debt” is such a common phrase in the developers world? Or why “code rot” is so rarely used as they are both essentially the same thing.

Actually I do know why.

  • “Debt” implies that at some point in the future time and resources will be made available to address the short cuts, the rushed code, the fixes to the fixes
  • “Rot” implies that what has been created is rotten, dead and worthless.

But how often is time, money and resources allocated to pay back the “debt”? Can you go to a client and say, “Yes its working well enough today but we can make it better” Or how do you demonstrate the return on investment to a client?

Maybe by having an explicit understanding how the rot develops can slow its progress. How about these 3 sources of debt/rot?

  • Deliberate debt. Limits on time and money necessitate the need for a quick delivery.
  • Accidental debt. Where decisions made early on in a project might not be the best solution as the project evolves and requirements change. Additional new functionality will become difficult and slow to implement. Incremental refactoring might not be the solution and a more rigorous approach to refactoring is needed
  • Unnecessary complexity through lots of incremental changes, often exacerbated when multiple individuals or teams work on discrete aspects of the code with out fully understanding of original code or design decisions

I’ve spoken to friends who work in other industries about this and I feel that coding in its many forms suffers from lack of scheduled/planned maintenance. Which is fine until 6/12/18 months down the line something stops working.

Vue.js – Azure Pipelines

I had a requirement to automate the CI/CD pipeline of an existing Vue.js project.

What was asked…

  1. On any merge into the branch “releases/dev
  2. Run all unit tests
  3. Build for the development/staging environment
  4. Copy the files to Azure Blob storage so they can be used as a SPA

The project repo was already in Azure Dev Ops

trigger:
  - releases/dev

pool:
  vmImage: "ubuntu-latest"

steps:
  - task: NodeTool@0
    inputs:
      versionSpec: "12.x"
    displayName: "Install Node.js"

- script: |
    npm install
    npm run test:unit
  displayName: "npm install"

- script: |
    npm run test:unit
  displayName: "npm run test:unit"

- script: |
    npm run build:dev
  displayName: "npm run build:dev"

- task: AzureCLI@2
  displayName: "Copy files to blob storage"
  inputs:
    azureSubscription: 'Faux-Development-ltd'
    scriptType: 'bash'
    scriptLocation: 'inlineScript'
    inlineScript: 'az storage blob upload-batch -d \$web --account-   name "blobStoreName" -s "dist" --connection-string "DefaultEndpointsProtocol=https;AccountName=xxxxxx;AccountKey=123456789123456789/qwerty/qwertybangbang==;EndpointSuffix=core.windows.net"'

The only sticking points where.

The blob store container is called $web which look like a variable in the shell script so I had to use \$web

JS does a string/number exist within a nested array collection?

I have the following and need to test if a user id is present anywhere in the collection.

const meetingCollection = [
  { id: "2", userIds: [12, 34, 55, 6, 7, 43543, 45345, 545] },
  { id: "21", userIds: [3, 425, 5, 33, 7, 68, 76, 99, 66, 99] },
  { id: "22", userIds: [767, 5654756, 5658, 86, 45, 23456, 666] },
  { id: "23", userIds: [6, 43562, 5645747, 4654, 2577, 4345, 45777] },
  { id: "24", userIds: [45645, 124, 4, 435, 6, 7755, 7, 8] },
  { id: "25", userIds: [1, 2, 455, 647, 753] },
]
const queryString = 7755;

meetingCollection.some(m => m.userIds.some(userId => userId === queryString))

Array.prototype.some() tests the method against each “row” of the collection and returns true on the first hit and then stops. If you have a 1000 elements and the method returns true on the 10th iteration .some() stops looping over the collection and returns true.

If a method fails to return true then false is returned.

The above example I’ve nested .some()

Try this in the console….

const meetingCollection = [
  { id: "2", userIds: [12, 34, 55, 6, 7, 43543, 45345, 545] },
  { id: "21", userIds: [3, 425, 5, 33, 7, 68, 76, 99, 66, 99] },
  { id: "22", userIds: [767, 5654756, 5658, 86, 45, 23456, 666] },
  { id: "23", userIds: [6, 43562, 5645747, 4654, 2577, 4345, 45777] },
  { id: "24", userIds: [45645, 124, 4, 435, 6, 7755, 7, 8] },
  { id: "25", userIds: [1, 2, 455, 647, 753] },
]

const findId = (queryString) => {
  return meetingCollection.some(m => m.userIds.some(userId => userId === queryString))
}

console.log(findId(2577)); // true
console.log(findId(257)); // false

JS rounding numbers

I have a requirement to be able to round numbers to either a whole number or to a specified number of decimal places….

Every now and then i find myself looking over my current solution to a problem when applying it in a new project. In this case it was very simple statistics and mean values.

For example:

const dec = [2, 678, 65.67467, 10.5452453453, 1, 0];
// Required outcome to 3 decimal places
// 2, 678, 65.675, 10.545, 1, 0

// Or to 2 decimal places
// 2, 678, 65.67, 10.55, 1, 0

My solution:

const round = (n, decimal = 2) => {
    return Math.round(n * Math.pow(10, decimal)) / Math.pow(10, decimal);
};
// Quick test
dec.forEach(n => {
console.log(round(n, 3));
});

dec.forEach(n => {
console.log(round(n));
});

As an aside: I need to have a set of numbers rounded and set with 2 fixed decimal places. So the same data set would be:

const dec = [2, 678, 65.67467, 10.5452453453, 1, 0];

// Required response would be
// 2.00, 678.00, 65.67, 10.55, 1.00, 0.00

There is the Number.toFixed() method

dec.forEach(n => console.log(n.toFixed(2)));

Finding, replacing, deleting and adding to a nested collection

Problem: I have an object that has a field call modules that is and array of activities. Activities is itself a complex and many nested object. I need to hunt for activities by their IDs and replace, delete or insert between existing objects

// Replace object in collection
Object.keys(data.modules).forEach(modKey => {
  Object.keys(data.modules[modKey].activities).forEach(activityKey => {
    if (data.modules[modKey].activities[activityKey].id === newActivity.id) {
      data.modules[modKey].activities.splice(activityKey, 1, newActivity);
    }
  });
});
// Remove object in collection
Object.keys(data.modules).forEach(modKey => {
  Object.keys(data.modules[modKey].activities).forEach(activityKey => {
    if (
      data.modules[modKey].activities[activityKey] &&
      data.modules[modKey].activities[activityKey].id === newActivity.id
    ) {
      data.modules[modKey].activities.splice(activityKey, 1);
    }
  });
});
// Insert object at index
const moudleIndex = 0;
const activityIndex = 2;

Object.keys(data.modules).forEach(modKey => {
  if (modKey == moudleIndex) {
    Object.keys(data.modules[modKey].activities).forEach(activityKey => {
      if (activityKey == activityIndex) {
        data.modules[modKey].activities.splice(activityKey, 0, newActivity);
      }
    });
  }
});

Visual Studio Code – colours

Background: I am working developing a number of Express.js micro services and at times I have two or three VSCode windows opened at once. After a long day it gets confusing which project I am working on.

To solve this I found out that you can change the colours of the top and bottom bars. Now each of the projects is colour coded and reduces my cognitive load a little bit.

In VSCode create a folder called .vscode an in that a file called settings.json. For the above dark green and off white colour scheme

{
  "workbench.colorCustomizations": {
    "titleBar.activeBackground": "#1d7e05",
    "titleBar.activeForeground": "#e1dcdc",
    "titleBar.inactiveBackground": "#1d7e05",
    "titleBar.inactiveForeground": "#e1dcdc",
    "statusBar.background": "#1d7e05›",
    "statusBar.foreground": "#e1dcdc"
  }
}

Top Tip

Don’t make the colours too bright or you will get “after image” which is a bit off putting.

https://en.wikipedia.org/wiki/Afterimage

REGEX Examples with explanations

A string 24 characters in length and only with hexadecimal letters and numbers

Example use: In MongoDb the unique id’s (ObjectId)

The string must be 24 characters long. ^ Starts of string or start of line, $ end of string or line; both dependent on the “multi-line mode”

/^{24}$/

Hexadecimal uses only the letters “a to f” and the number “0 to 9”

/^[a-f0-9]{24}$/

REGEX 2

Okay in the previous post we had found the “find” tool and realised we can do so much more with it using regular expressions (regEx).

To recap a regEx is

“a sequence of symbols and characters expressing a string or pattern to be searched for within a longer piece of text.”

\d = a character 0 to 9

\w = any character a to Z and 0 to 9

\s =  whitespace

Example:

\d\d\d will (using the find tool in your text editor) will highlight groups of 3 numbers in a string

\w\w\w\w\w will highlight groups of 5 characters

Notice how \w\w\w included numbers and letters

\s\s will highlight double spaces

Lets look for words that have only 4 characters.

A 4 letter word can be described as,

“a space followed by any 4 characters, followed by a space”

\s\w\w\w\w\s

Which can be rewritten as

\s\w{4}\s

But that will also include numbers. To ignore numbers

\s\w{4}[a-z]\s

Not quite there, if you are playing along you will notice that we are highlighting 4 letter words and the space before and after. What we need is to set boundaries.

\b\w{4}[a-z]\b

\b is a boundary, there are a few but for now lets stay with ‘spaces’. So with that you can find all four letter words