Javascript pre-increment vs post-increment vs increment-equal

Test on:
Node v.14.17.3

Pre-increment – increment then read the variable, example:
++j

Post-increment – read the variable then increment, example:
k++

Increment-equal – increment then read the variable, example:
l+=1

Test code:

console.log('--- j');
let j = 1;
console.log(++j);
console.log(j);

console.log('--- k');
let k = 1;
console.log(k++);
console.log(k);

console.log('--- l');
let l = 1;
console.log(l+=1);
console.log(l);

Test result:


Count Working Days

Tested on:
.Net Framework 4.8

Calculate working days (Monday, Tuesday, Wednesday, Thursday and Friday) given 2 dates.

For example:
– Monday 8/2/2021 to Wednesday 8/4/2021 is 2 days – In this case, 8/4/2021 is excluded because the time is not specified and in .Net it automatically assigned to 12:00 AM.
– Monday 8/2/2021 12 PM to Wednesday 8/4/2021 12 PM is 2 days.
– Friday 8/6/2021 12 PM to Tuesday 8/10/2021 6 PM is 2.25 days.

public static double GetWorkingDays(DateTime startDate, DateTime endDate)
{
    // Get next full day from start date and last full day of end date
    var nextFullStartDate = startDate.AddDays(1).Date;
    var lastFullEndDate = endDate.Date;

    // Calculate total days based on start and end's day of week
    var dayOfWeekFactor = (nextFullStartDate.DayOfWeek - lastFullEndDate.DayOfWeek) * 2;
    if (lastFullEndDate.DayOfWeek == DayOfWeek.Sunday)
    {
        // In .net, day of week for Sunday is 0, we need to change it to 7
        dayOfWeekFactor = ((int)nextFullStartDate.DayOfWeek - 7) * 2;
    }

    // Calculate working days (ie: Monday, Tuesday, Wednesday, Thursday and Friday)
    var workingDayCount = ((lastFullEndDate - nextFullStartDate).TotalDays * 5 - dayOfWeekFactor) / 7;

    // Subtract working days if full start date or last full end date is Sunday
    // Saturday is not included here because if startDate is Saturday the formula above would have excluded Saturday. If the endDate is Saturday, it would have been excluded too because the time would be Saturday 12:00 AM
    if (nextFullStartDate.DayOfWeek == DayOfWeek.Sunday || lastFullEndDate.DayOfWeek == DayOfWeek.Sunday)
    {
        workingDayCount--;
    }

    // Count the real start/end date
    if (startDate.DayOfWeek != DayOfWeek.Saturday &&
        startDate.DayOfWeek != DayOfWeek.Sunday)
    {
        var startDateFraction = (nextFullStartDate - startDate).TotalHours / 24;
        workingDayCount += startDateFraction;
    }

    if (endDate.DayOfWeek != DayOfWeek.Saturday &&
        endDate.DayOfWeek != DayOfWeek.Sunday)
    {
        var endDateFraction = (endDate - lastFullEndDate).TotalHours / 24;
        workingDayCount += endDateFraction;
    }

    return workingDayCount;
}

References:
Stackoverflow

Dynamic Azure Data Table Query

Tested on:
Node.js 14.17.3
Typescript 4.3.5
@azure/data-tables 12.1.0

Continuing on previous post.
To use dynamic query, we can replace the filter parameter with inline variable. For example:

    const propertyName = 'PartitionKey';
    const propertyValue = 'Stanford';

    const tableClient = azTableService.getTableClient('Student');
    const results = tableClient.listEntities({
      queryOptions: {
        filter: `${propertyName}` + odata` eq ${propertyValue}`
      }
    });

    for await (const result of results) {
      console.log(result);
    }

Turn Off VSCode Intellisense

  1. Press CTRL + SHIFT + P to open Command Palette.
  2. Type/choose “Preferences: Open Settings (JSON)”.
  3. Add or modify following settings in proper JSON format.

{
    "editor.suggestOnTriggerCharacters": false,
    "editor.quickSuggestions": {
        "other": false,
        "comments": false,
        "strings": false
    }
}

References:

https://code.visualstudio.com/docs/editor/intellisense#_customizing-intellisense

Null/Undefined Check in Typescript

Tested on:
Node.js 14.17.3
Typescript 4.3.5

Conclusion
To check whether an object is null or undefined, use either:

if (a == null) {
}

or

if (a) {
}

Few gotcha with both approaches:
1. Both approaches will not cover the case when let a = '' or let a: string = ''.
2. The second approach will fail when a is unexpectedly boolean value, ie: let a = false.

I personally prefer more explicit approach and would opt for first one. To work around checking whether object is an empty string, we can add:

if (a == null || a == '') {
}

Test Results

Azure Data Table Query In Typescript

Tested on:
Node.js 14.17.3
Typescript 4.3.5
@azure/data-tables 12.1.0

There are not many resources when it comes to querying Azure Storage’s Table.
This is official sample code from Microsoft:
https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/tables/data-tables/samples/v12/typescript/src/queryEntities.ts

It provides some example but not much.
This post will attempt to provide more extensive examples.

Querying Azure Data Table basically using Odata convention. There are 2 important (optional) properties, filter and select.
https://docs.microsoft.com/en-us/javascript/api/@azure/data-tables/tableentityqueryoptions?view=azure-node-latest

filter is use to exclude/include data based on criteria, similar to where clause in TSQL.
select is use to choosing which piece of data (column/property) that will be returned, similar to select clause in TSQL.

Dataset In Examples
Given the following data table structure and its entities.

Click image to enlarge.

Example 1
This code:

    const tableClient = azTableService.getTableClient('Student');
    const results = tableClient.listEntities({ queryOptions: { filter: odata`PartitionKey eq 'Stanford'` } });

    for await (const result of results) {
      console.log(result);
    }

Will result in:

Example 2
This code:

    const tableClient = azTableService.getTableClient('Student');
    const results = tableClient.listEntities({ queryOptions: { filter: odata`PartitionKey eq 'Stanford' and Major eq 'Business' or Major eq 'Robotic'` } });

    for await (const result of results) {
      console.log(result);
    }

Will result in:

Notice our filter query specified 3 conditions. One of the condition is PartitionKey eq 'Stanford', but a student whose partition key is 'MIT' is included in the result because the student’s major also meet our criteria. Next example solve this issue.

Example 3
This code:

    const tableClient = azTableService.getTableClient('Student');
    const results = tableClient.listEntities({ queryOptions: { filter: odata`PartitionKey eq 'Stanford' and (Major eq 'Business' or Major eq 'Robotic')` } });

    for await (const result of results) {
      console.log(result);
    }

Will result in:

Now we narrow down the criteria with parenthesis after and query, we only get student whose partition key is 'Stanford' and either major in 'Robotic' or 'Business'. Since no one in 'Stanford' major in 'Robotic', we only get 1 result back.

Example 4
This code:

    const tableClient = azTableService.getTableClient('Student');
    const results = tableClient.listEntities({
      queryOptions:
      {
        filter: odata`PartitionKey eq 'Stanford' and (Major eq 'Business' or Major eq 'Robotic')`,
        select: [`FirstName`, `Major`]
      }
    });

    for await (const result of results) {
      console.log(result);
    }

Will result in:

Same filter query as previous example but this time we add select option and only select the FirstName and Major.

Example 5
This code:

    const tableClient = azTableService.getTableClient('Student');
    const results = tableClient.listEntities({
      queryOptions:
      {
        select: [`FirstName`, `Email`]
      }
    });

    for await (const result of results) {
      console.log(result);
    }

Will result in:

We remove the filter query and leave the select option to only returne FirstName and Email. This example show that you can use both filter and select options or only one of them or none at all.

Easy Way to Write Odata Query
Follow these steps to write complex odata query.
1. Go to Microsoft Azure Storage Explorer.
2. On left pane, click to open the table you want to query.
3. On right pane you can see detail of entities in that table.
4. On the top (1), click ‘Query’, a query builder pane will open (2) – see screenshot below.
5. Specify the conditions you want to query.

6. Click on the ‘Text Editor’ button (1) and you will see the query in plain text (2) that can be copy/paste – see screenshot below.

Complete Code

import { odata } from '@azure/data-tables';
import azTableService from '../../services/common/az-table.service';

describe('AzureTable', () => {
  it('query', async () => {
    const tableClient = azTableService.getTableClient('Student');

    // Example 1
    const results = tableClient.listEntities({ queryOptions: { filter: odata`PartitionKey eq 'Stanford'` } });

    // Example 2
    // const results = tableClient.listEntities({ queryOptions: { filter: odata`PartitionKey eq 'Stanford' and Major eq 'Business' or Major eq 'Robotic'` } });

    // Example 3
    // const results = tableClient.listEntities({ queryOptions: { filter: odata`PartitionKey eq 'Stanford' and (Major eq 'Business' or Major eq 'Robotic')` } });

    // Example 4
    // const results = tableClient.listEntities({
    //   queryOptions:
    //   {
    //     filter: odata`PartitionKey eq 'Stanford' and (Major eq 'Business' or Major eq 'Robotic')`,
    //     select: [`FirstName`, `Major`]
    //   }
    // });

    // Example 5
    // const results = tableClient.listEntities({
    //   queryOptions:
    //   {
    //     select: [`FirstName`, `Email`]
    //   }
    // });

    for await (const result of results) {
      console.log(result);
    }
  });
});

References:
https://docs.microsoft.com/en-us/rest/api/storageservices/Querying-Tables-and-Entities
https://docs.microsoft.com/en-us/dynamics-nav/using-filter-expressions-in-odata-uris
https://docs.microsoft.com/en-us/azure/search/search-query-odata-select

MacOs Set Default Git Editor

Tested on:
MacOs Big Sur

Steps to set default git editor in MacOs:
1. Open Terminal.
2. Run the following command in Terminal:

git config --global core.editor "code --wait"

This will set the git’s global config to use Visual Studio Code as the editor. You can change the code --wait to any other application you desire.

Run Background Process With QueueBackgroundWorkItem

Tested on:
.Net Framework 4.8

Quick way to run background task utilizing hosting environment’s process.

var worker = new SomeWorker();
HostingEnvironment.QueueBackgroundWorkItem(ct => worker.StartProcess());

The SomeWorker() is a method that we want to run in the background.
Keep in mind, because the background process is run in the host, if the host is restarted (ie: IIS) the background process will be interrupted.

References:
https://www.c-sharpcorner.com/article/run-background-task-using-hostingenvironment-queuebackgroundworkitem-net-framew/

Jupyter Kernel Location

Jupiter Kernel location in both Windows/MacOs system. Useful when need to delete them.

Unix:
System: /usr/share/jupyter/kernels/usr/local/share/jupyter/kernels
Env: {sys.prefix}/share/jupyter/kernels
User:
~/.local/share/jupyter/kernels (Linux)
~/Library/Jupyter/kernels (Mac)

Windows:
System: %PROGRAMDATA%\jupyter\kernels
User: %APPDATA%\jupyter\kernels

References:
https://jupyter-client.readthedocs.io/en/stable/kernels.html#kernel-specs

ERR! Unexpected end of JSON input while parsing near ‘…’

There are many causes of this error. But the core issue is the same, corrupted NPM packages.

Here are possible solutions:
– Run npm clear cache --force.
– Delete node_modules folder and rebuild.
– Uninstall and reinstall Angular/CLI.
– Uninstall and reinstall NPM.

References:
https://stackoverflow.com/questions/47675478/npm-install-errorunexpected-end-of-json-input-while-parsing-near-nt-webpack

https://stackoverflow.com/questions/50189096/installing-create-react-app-gives-npm-err-shasum-check-failed-and-npm-err-unex/50191315#50191315