Tuesday, 24 December 2019

Generic method for builing a query string of classes in Typescript

This method below can be used in Typescript to build up a query string from a given object of a class instance in Typescript. Use it when performing HTTP(S) GET calls.

  BuildQueryString<T>(input: T): string {
    let q = "?";

    Object.keys(input).forEach(key => q += key + "=" + input[key] + "&");

    if (q.length > 0) {
      q = q.substr(0,q.length-1);
    }

    return q;

    
  }



Sample usage in Angular 8 solution of mine for example:


  async saveSurvey(): Promise<SurveyItem> {
    //debugger
    let s: SurveyItem = {
      Id: 0, LastUpdate: new Date(),
      EquipmentNumber: this.equpimentIdentifier, RoomNumber: this.roomIdentifier,
      PrimaryUsage: this.primaryUsage,
      IsInspected: this.GetBoolean(this.isInspected), IsNotFound: this.GetBoolean(this.isNotFound)
    };
    let q = this.fetcher.GetAPIUrl('savesurvey');
    q += this.fetcher.BuildQueryString(s);
    const response = await this.http.get<SurveyItem>(q, { headers: this.corsHeaders }).toPromise();
    //this.openSnackBar('Lagret utstyr ' + this.equpimentIdentifier);
    this.openSnackBar('Lagret utstyr ' + this.equpimentIdentifier + ' Laster inn liste for utstyr i samme rom også..');

    //After saving survye - update also the properties with updated Id and LastUpdate

    this.SetCurrentSurveyItemPropretiesFromSurveyItem(response);

    this.onRoomSelected(this.roomIdentifier);



    return response;
  }

Monday, 2 December 2019

Eslint Standalone tool

I have created a standalone Eslint tool the last weeks! This tool is available through Npmjs here: https://www.npmjs.com/package/eslint-standalone The source code is available here: https://github.com/toreaurstadboss/eslint-standalone To clone the repo, you can run this command:

git clone https://github.com/toreaurstadboss/eslint-standalone.git

This animated gif shows how the tools shows linting capabilities. The loaded .eslintrc.js file errors if there are ES6 syntax, which does not work well in Internet Explorer. This is done by specifying env->es6 set to true and parserOptions->ecmaVersion set to '5'. Why would you even consider supporting Internet Explorer as a browser for your products ? Well, in the real world, some customers still use Internet Explorer due to company restrictions and compability reasons. So this standalone tool together with .eslintrc.js file below should help you check files conforming to ES5 Syntax and thereby supporting Internet Explorer.

module.exports = {
  "plugins": ["ie11"],
  "env": {
    "browser": true,
    "node": true,
    "es6": false
  },
  "parserOptions": {
    "ecmaVersion": 5,
  },
  "rules": {
    "ie11/no-collection-args": ["error"],
    "ie11/no-for-in-const": ["error"],
    //"ie11/no-loop-func": ["warn"],
    "ie11/no-weak-collections": ["error"]
  }
};

To check that your Javascript code works using this tool, add the .eslinrc.js file above in the folder of your project (or any parent folder on that media disk volume). Then run the command eslint-standalone.exe after adding the .eslintrc.js file. You should then have outputted to the command line the errors (or warnings found) of ES6 Syntax, which IE does not support. Note that I have not added functionality for '--fix' with this ESLint tool yet. You must inspect the warnings and errors reported and manually adjust/fix the Javascript source code. Also note that this tool only supports looking at .js and .htm and .html files. I tried adding .cshtml files in the list of file globs supported, but the tool could not understand Razor syntax. Feel free to give me some tips here if you know how to add this as a support. Also note that it is additional documentation to be found for this tool on the Npmjs.org site and also in the GitHub repository.
eslint-standalone.exe 
The sample screen shot shows how to run the tool from the command line (simple command). I deliberately added an arrow method in a Javascript file and the tool quickly spots this issue. For a medium sized project the tool takes only 5-10 seconds to execute.

Friday, 15 November 2019

Sorting array word-wise in Javascript

Sometimes it is nice to sort arrays word-wise in Javascript. This means sorting not the entire column value,

/**
 * Summary: Sorts alphabetaically word-wise to be used in e.g. a Select2Js control. Specify the n-word to start sorting with. 
 *
 * Alphabetically sorts by each word
 * @param {Number}   startWordIndex The 'n-word' to begin sorting with  *
 * @param {boolean}  isAscending The direction of sorting - true means ascending, false means descending
 * @return {type} Return sort comparison value. If 0, the sorting is tie, if < 0 the element a preceeds b
 */
(function () {
    var sortFunction = function sortFunctionTemplate(isAscending, startWordIndex, valueSelector, a, b) {
        var aValue = valueSelector(a);
        var bValue = valueSelector(b);
        var astripped = aValue.split(' ');
        var bstripped = bValue.split(' ');
        var wordLength = Math.min(astripped.length, bstripped.length);

        var compareValue = 0;
        for (var i = startWordIndex; i < wordLength; i++) {
            compareValue = astripped[i].localeCompare(bstripped[i]);
            if (compareValue !== 0) {
                break;
            }
        }
        if (compareValue === 0) {
            if (astripped.length > bstripped.length) {
                compareValue = 1;
            } else if (astripped.length < bstripped.length) {
                compareValue = 1;
            }
        }
        return compareValue * (isAscending ? 1 : -1);
    };
    if (typeof (Array.prototype.sortWordwise) === 'undefined') {
        // ReSharper disable once NativeTypePrototypeExtending
        Array.prototype.sortWordwise = function sortWordwise(startWordIndex, isAscending, valueSelector) {
            if (valueSelector === null) {
                valueSelector = function (item) {
                    return item;
                };
            }
            //console.log('sorterer word-wise... ');

            return this.sort(sortFunction.bind(this, isAscending, startWordIndex, valueSelector));

        };

    }
})();

Example how to use this method: Here we use the Select2.js jQuery plugin to do our custom sorting to sort word-wise. I only consider the text after the ':' in my specific use case and I supply the starting index - sorting by the nth-word 1 (i.e. second word and so on) and supply a value selector function also. Select2.Js also retrieves a matcher function to specify the matching to be done case-insensitive (the find item in list function of the select 2 js control in this specific case).

$('.stentGraftfabrikatpicker').select2({
      width: "element",
            sortResults: function(data) {
                var velgVerdi = data[0];
                var ret = [velgVerdi];
                var dataToBeSorted = data.splice(1);
                return ret.concat(
                    dataToBeSorted.sortWordwise(1, true, function(item) {
                        var value = item.text;
                        return value.indexOf(':') >= 0 ? value.substring(value.indexOf(':') + 1) : value;
                    })
                );
            },
      matcher: function(term, text) {
       return text.toUpperCase().indexOf(term.toUpperCase()) >= 0;
      },
      allowClear: true
    });

AngularJS Directive for Focus trap for modal popups

If you use Bootstrap modal popup, chances are that hitting TAB enough types on the keyboard will navigate out of the modal popup and back to the background web page, the DOM elements "beneath" the modal popup. This AngularJS directive should fix up that, wrapping everything in an IFE (Immediately invoking Function Expression). Note that this only works if your module is called 'app' (the default name).

(function() {
angular.module('app')
 .directive('modal', trapFocus)
 
 function trapFocus() {
        return {
            restrict: 'C',
            priority: 1,
            link: function (scope, element, attr) {
                if (typeof (scope.registerFocusTrap) === 'undefined') {
                    scope.registerFocusTrap = registerFocusTrap;
                } else {
                    for (var i = 0; i < element.length; i++) {
                        registerFocusTrap(element.get(i));
 
                    }
                }
 
            }
        };
    }
 
    function registerFocusTrap(element) {
        var focusableEls = element.querySelectorAll(
            'a[href]:not([disabled]), button:not([disabled]), textarea:not([disabled]), input[type="text"]:not([disabled]), input[type="radio"]:not([disabled]), input[type="checkbox"]:not([disabled]), select:not([disabled])');
        var firstFocusableEl = focusableEls[0];
        var lastFocusableEl = focusableEls[focusableEls.length - 1];
        // ReSharper disable once InconsistentNaming
        var KEYCODE_TAB = 9;
 
        $(element).on('keydown',
            function (e) {
                console.log('inside registerFocusTrap keydown');
                var isTabPressed = (e.key === 'Tab' || e.keyCode === KEYCODE_TAB);
 
                if (!isTabPressed) {
                    return;
                }
 
                if (e.shiftKey) /* shift + tab */ {
                    if (document.activeElement === firstFocusableEl) {
                        lastFocusableEl.focus();
                        e.preventDefault();
                    }
                } else /* tab */ {
                    if (document.activeElement === lastFocusableEl) {
                        firstFocusableEl.focus();
                        e.preventDefault();
                    }
                }
            }
        );
    }
  
}); 
 

Note that the name of registered modules in AngularJs is not supported in AngularJs by itself. This polyfill should tough fix up this.

(function(orig) {
    angular.modules = [];
    angular.module = function() {
        if (arguments.length > 1) {
            angular.modules.push(arguments[0]);
        }
        return orig.apply(null, arguments);
    }
})(angular.module);

Sunday, 10 November 2019

Implementing projection in Javascript

Github page for source code in this article:
https://github.com/toreaurstadboss/JsLinqSimpleProjection
https://www.npmjs.com/package/jslinqsimpleprojection
Npm package for source code in this article: Since I started working with Linq in C#, I missed a good way of doing much of the same functionality in Javascript. Today, there are several Linq libraries for Javascript and Typescript, and libraries such as Backbone.Js or Lodash also containing a lot of helpful operators or utility methods. As an educational exercise, I was looking into a simple way of doing a projection method in pure Javascript (no es6 syntax). Here is what I made. First off, we need to be able to project an array of objects by listing up properties. In ES6 Javascript we could use arrow functions. But I wanted to support pure Javascript. So I choose to use a comma separated list of property or field values to dive into the array object, written in Json notation of course. Consider first this array as an example:

        var someCountries = [
          { country: "Norway", population: 5.2, code: "NO" },
          { country: "Finland", population: 5.5, code: "SU" },
          { country: "Iceland", population: 0.4, code: "IC" },
          { country: "Sweden", population: 10.2, code: "SW" }
        ];

We want to project this array using a new method select on the array of which we use the Array.prototype to achieve. Note that this will immediately add methods to all array objects immediately in the global scope. Now consider a projection of just the 'country' and the 'population' fields of the Json structure. Given a method call of just these two properties, we want to create a select projection method. First consider this lightweight linqmodule implementation, using an IFE (Immediately invoked function expression) and using the revealing module pattern. We expose the method dump to this module.

var linqmodule = (function() {
  projection = function(members) {
    var membersArray = members.replace(/s/g, "").split(",");
    var projectedObj = {};

    for (var i = 0; i < this.length; i++) {
      for (var j = 0; j < membersArray.length; j++) {
        var key = membersArray[j];
        if (j === 0) {
          projectedObj[i] = {};
        }
        projectedObj[i][key] = this[i][key];
      }
    }

    return projectedObj;
  };
  Array.prototype.select = projection;

  dumpmethod = function(arrayobj) {
    var result = "";
    result += "[";

    for (var i = 0; i < Object.keys(arrayobj).length; i++) {
      var membersArray = Object.keys(arrayobj[i]);
      for (var j = 0; j < membersArray.length; j++) {
        if (j === 0) {
          result += "{";
        }
        var key = membersArray[j];
        result +=
          "key: " +
          key +
          " , value: " +
          arrayobj[i][key] +
          (j < membersArray.length - 1 ? " , " : "");
        if (j === membersArray.length - 1) {
          result +=
            "}" + (i < Object.keys(arrayobj).length - 1 ? "," : "") + "\n";
        }
      }
    }
    result += "]";

    return result;
  };

  return {
    dump: dumpmethod
  };
})();


Now it is easy to dump the contents of our projected array (which is copied into a new object) using the dump method:

 result = someNums.select("country,population");
         document.getElementById("result").innerText = linqmodule.dump(result);

        console.log(result);

Note that our new object contains only the country and population fields in the Json structure, not the code. We have created a simple projection mechanism in Javascript in a self contained module!

Arithmetic parser in Javascript

I just added an arithmetic parser in Javascript code sample on Github, check out the following repo: JsSimpleParser The parser is also available through Npm: https://www.npmjs.com/package/simplejsparsermatharithmetic Installation: npm i simplejsparsermatharithmetic Supported expressions (examples): 2+3 should evaluate to 5 12 * 5–(5 * (32 + 4)) + 3 should evalute to -117 This is a great example of how to write a parser of your own.

Sunday, 13 October 2019

Using TagBuilder in MVC

I have been started programming MVC again at work after many years focusing more on WPF. So I came accross a class called 'TagBuilder'. This is a handy class for generating markup programatically. Let us create a HTML helper that renders an image tag. It can use TagBuilder to achieve this. First off, we create the HTML helper like this:
using System.Web;
using System.Web.Mvc;

namespace HelloTagBuilderDemo.Helpers
{
    /// <summary>
    /// Sample usage of TagBuilder in MVC
    /// </summary>
    public static class HtmlHelpers
    {
        /// <summary>
        /// Generates an IMG element which is self-closing and uses as src the given path pointing to an image file with a relative path within the web application
        /// and with alternate text
        /// </summary>
        /// <param name="path"></param>
        /// <param name="alternateText"></param>
        /// <returns></returns>
        // ReSharper disable once UnusedParameter.Global
        // ReSharper disable once InvalidXmlDocComment
        public static IHtmlString Image(this HtmlHelper htmlHelper, string path, string alternateText)
        {
            var builder = new TagBuilder("img");
            // ReSharper disable once StringLiteralTypo
            builder.Attributes.Add("src", VirtualPathUtility.ToAbsolute(path));
            builder.Attributes.Add("alt", alternateText);
            var markupResult = builder.ToString(TagRenderMode.SelfClosing);
            return new MvcHtmlString(markupResult);
        }
    }
}

We make use of the VirtualPathUtility.ToAbsolute method to convert a virtual path to an absolute path. Then we make use of the html helper inside a MVC view like this:

@{
    ViewBag.Title = "Home Page";
}

@using System.Web.Mvc.Html
@using HelloTagBuilderDemo.Helpers


<div class="jumbotron">
    <h1>ASP.NET</h1>
    <p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.</p>
    <p><a href="https://asp.net" class="btn btn-primary btn-lg">Learn more »</a></p>
</div>

<div class="row">
    <div class="col-md-4">
        <h2>Getting started</h2>
        <p>Harold is at it again, making clones of himself to inflict multiple pain.</p>                
    </div>
    <div class="col-md-4">
        @Html.Image(@"~/Images/haroldatitagain.jpg", "Harold")
    </div>
</div>
And now we have our resulting HTML helper at display, showing also in the screen grab the markup the HTML helper generated for us. [1] Tagbuilder on MSDN: https://docs.microsoft.com/en-us/dotnet/api/system.web.mvc.tagbuilder?view=aspnet-webpages-3.2

Sunday, 29 September 2019

Deleting a set of databases with similar names with T-SQL

Devops Sunday. If you end up having many databases in SQL Server and want to get rid of them by matching their names, this T-SQL should help you out.

use master
go
declare @tablestoNuke as table(db nvarchar(100))
insert into @tablestoNuke
select name from sys.databases  
where name like '%SomeSimilarDbNameSet%'
declare @nukedb as nvarchar(100)
declare @nukesql as nvarchar(150)

declare nuker cursor for
select db from @tablestoNuke

open nuker
fetch next from nuker into @nukedb

while @@FETCH_STATUS = 0 
begin
set @nukesql = 'drop database ' + @nukedb
exec sp_executesql @nukesql
fetch next from nuker into @nukedb
end

close nuker
deallocate nuker

print 'All done nuking'


The T-SQL uses a cursor to loop through the database names fetched from sys.databases view on master db and then uses exec sp_executesql to delete the databases, by dropping them.