Category Archives: JavaScript

How to handle async functions inside constructors in TypeScript

In this post we will discuss some options you have with calling async functions in constructor of your TypeScript classes.

So, first of all – why would you do this? Well, maybe you need some data from a web API to fill the object with data, or you need some input from user, or some API in code from a colleague is async. Reasons may vary, but the problem is still the same :
in TypeScript, you can’t have await statement in constructor, because constructor returns instance of object, not Promise<yourObjectType>. (All of this indeed is tied to current version of TypeScript 2.2. maybe in future with native async/await keywords in JS, things will change).

So, possible solutions depend on what happens in your async functions and if you need results from this call / calls at the time you return the object.

Solutions :

1. Try to avoid async stuff in constructor. As said earlier, constructor is a function, that should initiate the object in some way and return it immediately, not return a promise that has to be awaited. That is considered a bad practice and TypeScript doesn’t allow this. More on this problem here

http://stackoverflow.com/questions/11856778/asynchronous-constructor

http://stackoverflow.com/questions/24398699/is-it-bad-practice-to-have-a-constructor-function-return-a-promise

http://stackoverflow.com/questions/36363278/does-async-await-will-allow-us-to-be-used-on-constructors

So in some sense, need for async stuff in your constructor might be considered code smell, you are doing too much in constructor. Refactor your code.

2. If you want your async code to stay in constructor for some reason, do you need results from async calls? If not and you want to call them and let them just execute, you might consider calling async functions without await. In this way you will unfortunately be unable to receive (await) the result from these calls (values passed back via resolve).
Please note, that this might result in some non deterministic issues because of how JS handles async code and I really don’t recommend this. Also another downside is, that if you would wrap everything inside constructor with try, promises that would be rejected (analogy with throwing exception in async sense will be not caught but become unhandled exceptions).

Your constructor might then look like this :

class SomeClass1 {
  constructor() {
    getConfirmAsync("1 - 1");
    getConfirmAsync("1 - 2");
    getConfirmAsync("1 - 3");
  }
}

Sample with try/catch block might look like this :

class SomeClass2 {
  constructor() {
   try {
     delayAsync(3000);
     delayAsync(2000);
     delayAsync(1000);
   } catch (e) {
     console.log(e);
   }
  }
}

No awaits means that code will continue to run and your constructor will finish and hand over new instance of your class sooner than code triggered from constructor will finish its execution. Scary, right? Don’t do it!!!!

Another take on this same approach is to leave an async self executing function in constructor like this :

class SomeClass3 {
  constructor() {
    console.log("SomeClass3 - entry");
      (async () => {
        try {
          await delayAsync(3000);
          await delayAsync(1000);
          await delayAsync(2000);
        } catch (e) {
          console.log(`catch triggered with exception ${e}`);
        }
      })();
      console.log("SomeClass3 - exit");
  }
}

Again, object would return from constructor but it would still lack calls to all async functions but this time, with proper async function, await and try/catch will work. So if for some reason first function would throw, all the others will not be hit (you can try to change the first call from 3000 to 2999 and see the results). Again, this is not recommended!

3. Simple “factory” function :

This is a way you might potentially want to go because it’s the safest one. All calls will be awaited and instance of you class will be in the state it should be.
All logic from constructor would have to be removed and stored in function that will have the logic of preparing object to the right shape. But, it is OK to separate the logic of creation from class to different function/files that knows what to do to make the object “right”?
Also you might want for safety reasons to “hide” somehow the class itself to prevent from instantiation without the factory function.
This could be done by exporting (from module) only interface of the object and “factory” function and not the class itself. Downside is, that all functions that are called in “factory” function need to be also public because “factory” function is not inside the class itself, but it is a separate function.

//exporting interface so we can work with the object outside
export interface ISomeClass {
	stringPublic: string;
	numberPublic: number;
}
 
//not exported = not visible
class SomeClass implements ISomeClass {
	public stringPublic: string;
	public numberPublic: number;
 
	private somePrivateFn() {
		console.log("this is private fn");
	}
}
 
export async function createSomeClassAsync(): Promise<SomeClass> {
	let res = new SomeClass();
 
	await delayAsync(1000);
	await getConfirmAsync("1");
	await delayAsync(3000);
	await getConfirmAsync("2");
	await delayAsync(2000);
	res.numberPublic = 1;
	res.stringPublic = "aa";
	// res.somePrivateFn(); since we are not inside function this would fail
 
	return res;
}

This is TS that has export and import statements, but in my examples on GitHub I have this implemented without export and import. I can make a sample for you that is using modules (like the one above) but I decides to cut complexity for my readers and not use any bundling tool like webpack or browserify (I recommend webpack over browserify but that is just a matter of taste).
5. You want to hook a browser event inside the constructor , like some ready event or some other that will trigger some async functions once it happened.

Your constructor might look like this :

function ready(fn) {
    if (document.readyState !== "loading") {
        fn();
    } else {
        document.addEventListener("DOMContentLoaded", fn);
    }
}

class SomeClass {
    constructor() {
        console.log("SomeClass5 - entry");
        ready(async () => {
            try {
                await delayAsync(3000);
                await delayAsync(1000);
                await delayAsync(2000);
            } catch (e) {
                console.log(`catch triggered with exception ${e}`);
            }
        });
        console.log("SomeClass5 - exit");
    }
}

I am using a helper function from http://youmightnotneedjquery.com/ to avoid adding jQ to the project, but you get the point.

If my samples doesn’t make sense for you, please to to my GitHub repo, you can find all the code I made as examples can be found there : https://github.com/rostacik/asyncTsCtorSolutions .

If  you have TypeScript installed as global npm package, just type

tsc

in the root. If you dont have TypeScript installed, you just need to do to install npm packages :

npm install

and run TypeScript compiler to build all .ts files :

 "node_modules/.bin/tsc.cmd"

Feel free to ask or discuss in the comments 🙂

How to filter particular TypeScript errors in build result

Hi interwebz.
I just want to share this short poor man’s fix when migrating TypeScript to filter out some particular errors in TypeScript build.

Why the hell you (might) need it?

So what would be the common use case , why to bother mask/mute errors on build? Compile is the first test our code need to undergo, like first pass of “unit tests”.

Our situation : currently we have a lot of .js files that let’s say most of the time worked and we need to iterate on way to migrate fully from JavaScript only to TypeScript only. So we rename .js to .ts and then we ran into errors like (among others) :

  1. error TS2365 Operator ‘>=’ cannot be applied to types ‘string’ and ‘number’.
  2. error TS2365 Operator ‘==’ cannot be applied to types ‘string’ and ‘number’.
  3.  error TS2345 Argument of type ‘number’ is not assignable to parameter of type ‘string’.

Yes indeed these are against the “logic” of TypeScript – bring types to JavaScript. But I know I want it there for some short timespan. Just to test. I don’t want to wade through 1500 same errors I know I will have to fix, but among them TypeScript also tells me big and real problems, but buried under many same errors about types.

We are not alone in this, more ppl write about it here :
https://github.com/Microsoft/TypeScript/issues/6114

https://github.com/Microsoft/TypeScript/issues/4094

https://github.com/Microsoft/TypeScript/issues/9448

and also here https://github.com/Microsoft/TypeScript/issues/11051

Solution :

So the solutions vary from custom branch of TypeScript as such to stupid grep on the command line output. And since I am on Windows 10 (my dev box) , I chose to stick with PowerShell so this is snippet that should do the job.

Lets say we want to mute TS2365 and TS2345 errors and your TS build gulp task has name someTSBuildTaskName.

PS script – output to some file :

node .\node_modules\gulp\bin\gulp.js someTSBuildTaskName --color | Select-String -NotMatch "TS2365" | Select-String -NotMatch "TS2345" | Out-File "grepts.txt"

PS script – output just to console (just drop the last part after pipe) :

node .\node_modules\gulp\bin\gulp.js someTSBuildTaskName --color | Select-String -NotMatch "TS2365" | Select-String -NotMatch "TS2345"

PS: I am calling here the gulp task without gulp installed with -g flag (global) so you can just call

gulp someTSBuildTaskName

with globally installed gulp and you are also good to go.

Found any better solution? Pls let us know in comments! 🙂

AD: you can also use this console log parser on Jenkins:

Regular Expression :

([\w\\\.]+)\((\d+),\d+\):\s+\w+\s+((?!TS2365|TS2345)\w+):\s+(.*)$

Mapping Script :

import hudson.plugins.warnings.parser.Warning

String fileName = matcher.group(1)
String line = matcher.group(2)
String category = matcher.group(3)
String message = matcher.group(4)

return new Warning(fileName, Integer.parseInt(line), "TS Error", category, message);

and plug this into your build pipeline.

How to make CKEditor load just like a frame but show upper command buttons when maximized to fullscreen

Here is my small take on what is needed in lots of apps that have limited real estate on the screen. To load some (in my case CKEditor) editor with hidden chrome, buttons that are either shared for several editors, or each editor has its own set, you name it. There are limitless possibilities of what your client would like to have/see/use.

My sample is loading CKEditor with hidden build in controls and using own buttons. Once in fullscreen the editor will fill the screen and we can also show controls.

Here is the sample repo :

https://github.com/rostacik/CKEditorPlayground

and here you can see directly the result :

https://rawgit.com/rostacik/CKEditorPlayground/master/CKEditorPlayground/index.html

Feel free to reuse, enjoy.

How to get type of object in TypeScript, when using union types and type guards for multiple types of function parameter or variable

tl;dr

When checking for primitive types in TypeScript , typeof variable === “string” or typeof variable === “number” should do the job.

When checking for HTMLElement or HTMLDivElement type of objects, variable instanceof HTMLElement or variable instanceof HTMLDivElement type of check should be the right one.

Please note that this is somewhat simplified point of view. I was only using simple objects and elements from one page. If you will run into some specialties, please read this article : http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/ and write as much unit tests as possible for you scenario. There might be some scenario where using typeof and instanceof are simple not enough.

The whole story :

My beloved TypeScript 1.4 we got a while back came with a new lovely possibility of having parameters passed as object that might be of several different types. For example you can accept either string or array of strings, where if passed a plain string, you can split it and continue with array of strings or use directly passed array.

We can argue if this is a good and clean solution from architectural point of view, but if for whatever reason this will be a requirement how the function should work, than we can leverage two sweet features of TypeScript :

Both might be used also separately or with some plain var in your code (you can just define var that will be of types string | HTMLElement | number) but if used together, Type Guards are building on top of Union Types feature and giving you some sweet stuff.

So what you get is, that TypeScript now understands what are you doing, when you check for one of types that variable might be of and you can get IntelliSense for that type (I am little fast forwarding here to the function I want to show you but this is what I mean by that) :

param check intellisense

And here I am getting to the main point of this particle and that is : how can we check for HTML elements of any other object from the DOM world?

As you all know, getting the basic types in JavaScript if quite difficult if you run into edge cases or the type you check for might be also array or stuff like that. You can read great article like this one : http://stackoverflow.com/questions/332422/how-do-i-get-the-name-of-an-objects-type-in-javascript. There are many caveats. 🙁

typeof will do, for the most part :

But most of the time, for basic types we are OK with using typeof operator and comparing against “string” or “number” but what about HTMLElement or HTMLDivElement object in TypeScript? Do the exist in the vast and wild JavaScript world? Yes the do exist, but dependent on the browser age with different results. Another misleading thing is that unfortunately the typeof operator will not work we want for HTMLElement and similar types of objects, but neither will the approach create an error, because every time we would get string “object” which is OK from inheritance point of view but its not what we need.

instanceof to the rescue :

What will work here is instanceof operator.  Nice article also here : http://stackoverflow.com/questions/7313559/what-is-the-instanceof-operator-used-for. Again, there are some caveats here (like this http://stackoverflow.com/questions/472418/why-is-4-not-an-instance-of-number) when used with primitive types like string, so I advice you to stick with instanceof for instances of objects or for checking of types from the DOM side of the world.

The snippet :

And here it is ladies and gentleman, the glamorous sample snippet I wanted to share with you (for testing purposes):

export function parCheckDemo(param: string | number | HTMLElement | HTMLImageElement | HTMLDivElement): void {
    if (param instanceof HTMLDivElement) {
        console.log('HTMLDivElement');
    } else if (param instanceof HTMLImageElement) {
        console.log('HTMLImageElement');
    } else if (param instanceof HTMLElement) {
        console.log('HTMLElement');
    } else if (typeof param === "string") {
        console.log('string');
    } else if (typeof param === "number") {
        console.log('number');
    } else {
        console.log("You're not supposed to be here! - Levelord");
    }
}

Hope this helps dear reader, enjoy. If you have any suggestions to the code, please feel free to share in the comments.

PS: yes, in real life I (and you too) should probably first check if anyone passed something as param argument , this snippet is jut for demo purposes.

moment.js with locale doesn’t parse locale dates / it displays malformed strings with punctuation

The problem :

So, you wanted to use momentjs to parse from locale date and time and/or month and day names , or you wanted some locale output from date using .format in your browser, but what you received was a mess?

Sample solution to play on/investigate :

Here : https://github.com/rostacik/moment-js-with-locales-demo you can find a sample solution with reproduction of the problem and samples how to fix the problem. Feel free to reuse.

What happened :

Basically the problem is following thing : file moment-with-locales.js with localized names of dates, moths, etc. contains UTF8 characters. But, it is saved as UTF8 without BOM (at least, that is what Notepad++ says). Which is OK for text editors, but browsers needs to know somehow upfront. Otherwise this is going to happen to special characters and in this way they will be parsed :

malformed moment js with locale

The tricky part is, that JavaScript command as such are valid. What is not are string literals with special characters, nothing more.

So how can you tell browser that what we need is this? :

correct moment js with locale

 The solution :

To keep is simple stupid, you either :

  • Use UTF8 with BOM (byte order mark) and you can/need to keep just plain <script reference (but you will need to reencode every new version of moment.js there will be),
  • Use plain <script reference but you will set up yout web server in a way it will add response header for .js files with Content-Type set to application/javascript; charset=utf-8 (normally there is only application/javascript),
  • Use <script tag but force also charset=”utf-8″ on it.

BTW you also need to use <script charset=”utf-8″ on files that are from cdnjs. You can find sample in my github repo.

Hope this helps.

If you have any other ways of making moment.js work with locales in the browser, than please feel free comment under the article or mail me.

Dušan

window.showModalDialog behaves differently on IE, FireFox and on Chrome

I would like to share one small “feature” I have found on current latest browsers. By “latest browsers” I mean (I tested this behavior on IE 11, FireFox 29 and Chrome 37).

The problem:
If say for whatever reason you are using JavaScript modal dialogs with

window.showModalDialog()

like in older web app (chrome and firefox displays waring you should use

window.open()

instead, more on this here : http://stackoverflow.com/questions/20733962/why-is-window-showmodaldialog-deprecated-what-to-use-instead ) and you are passing in multiple same arguments (for whatever reason, maybe you had default values + new values as params and previously IE took second parameter, that is the mystery of legacy code and I don’t suppose majority of you will do this, but it might happen), than you will have problem on FireFox.

So given JavaScript call like this

window.showModalDialog('HtmlPage1.html', null, 'resizable:0;status:0;dialogwidth:900px;dialogheight:200px;dialogwidth:100px;dialogheight:300px');

the following will happen :

no Error will be thrown, IE and Chrome will use second pair of dialogwidth and dialogheight, FireFox will use first one and all of these popups will be styled using these values so the same code will result in different UX.

Small side note though, Chrome will make dialog really 100px and IE will hit some internal min value I suppose and Chrome’s window will not be modal (you can click away) but  everywhere the window will be opened.

Hope this might save you some time in case you run into the same problem.

JavaScript Visual Studio snippet for is object defined check

Since I write a lot of JavaScript currently in Visual Studio these days, I lack one of the very common checks in JavaScript and that is testing if object exists.

I mean this check :

if (typeof (someObject) !== 'undefined') {

someJSCodeHere();

}

If you want to use this code but not type it each time over and over again and speed your work up you probably thought a snippet that would save your keystrokes would come handy, but there is none in vanilla VS. So, you can use my snippet ,just import it to Visual Studio from Code Snippet Manager window (in VS 2013 – CTRL + K + B) and use it with typing def and then tab (or use CTRL + K + X and pick one).

Enjoy your speedup while working with JavaScript.

PS : do you know you can share snippets with your team mates?

http://blogs.msdn.com/b/zainnab/archive/2010/08/19/sharing-snippets-with-your-team-vstiptool0075.aspx

http://blogs.msdn.com/b/saraford/archive/2007/12/14/did-you-know-how-to-share-code-snippets-with-your-team.aspx

PS2: If you want to edit snippets in you VS, this plugin might be a good idea : http://snippetdesigner.codeplex.com/

How to setup post build event in Visual Studio to combine multiple TypeScript files to one JavaScript file

Hi interwebz and TypeScript users.

Just wanted to share this small idea/snippet I found on the web (the main reason to write this post was to let you skip my errors so you don’t have to find what to suffix after $(SolutionDir) and let tsc be happy with what VS is calling).

For example here : http://stackoverflow.com/questions/12926830/typescript-compiling-as-a-single-js-file

So, if you are using TypeScript and if you are wondering : “maybe I could stitch my 2-3-4 files together, that are used together in one .js file” , well that is of course possible.

Like this :

Make a post-build event, for each combined file you need to make one separate entry like this (with some sample project name and folder name here) :

tsc –out “$(SolutionDir)WebApplication1\TypeScript\Merged\two.js” “$(SolutionDir)WebApplication1\TypeScript\file1.ts” “$(SolutionDir)WebApplication1\TypeScript\file2.ts” –removeComments

Side note : Without specifying whole folder also after –out, tsc will output the combined file to bin, which is something you don’t want I presume.

And yes, you will also see errors if they happen in VS output window.

Another and maybe better take/steps would be to minify this combined .js or use Bundling and Minification built into .NET, but this is just another no code approach/tweak.

Enjoy….

AD:

I forgot to tell you about thing TypeScript added in later releases and that is , you can merge all JavaScript code to a single file in project properties here :

combined typescript js

However, I was not able to find any way to fine tweak and bind specific .ts files together so you can choose what you want in your project maybe event without any post build event. The path where VS stores the combined file is from the root of the project.

AD2: If you are using features from EcmaScript 5 in your TypeScript, than you need to pass also -t “ES5” parameter to the tsc, because otherwise build will fail. Small side note here, that ‘ES5’ doesn’t work, as they claim in help in the command line from tsc.exe itself.

AD3: You also should not forget to remove comments with –removeComments , since I presume you need this approach to minimize file size.

AD4: If you are extending some class in one of your file, you have to include this .ts file in the input files as well. (You will get exception that compiler cant find symbol – the class you inherit from, so you will know 🙂 )

How to subscribe to document.ready event from multiple TypeScript files

What I needed :

I needed to subscribe from multiple TypeScript files to ready event of document, the usual event where you hook to do some initializations with jQuery, when you need it. There are more ways, to do this.

  • You can handle the ready event on the “host” page and do what you need to do there,
  • You can, if you know you are the only one just inject your anonymous function to say window.onload but there is a problem, that the last pointer wins and you can have only one function there, just try this in you page :
    <script>
             window.onload = function() {
                 console.log('1');
             };
             window.onload = function () {
                 console.log('2');
             };
    </script>
    

    There will be only one line in console, with 2.

  • Somehow subscribe to the ready event and call all pointers no matter who subscribed and will subscribe in the host page.

First of all there are some things to clarify :

How to do it :

Since TypeScript is in fact JavaScript (its superset of JavaScript), you can use it without TS (btw I don’t use any feature from TS, maybe we could change

$(document).ready(function () {
         console.log('ts 2');
});

to :

$(document).ready(() => {
         console.log('ts 1');
});

But whatever 🙂

The key is to :

  • use jQuery in your project,
  • use everywhere $(document).ready since it will subscribe your code to the jQuery ready event and essentially chain them it the order as browser parsed the .js files,
  • include jquery.d.ts definition for TypeScript to be happy (part from DefinitelyTyped project)

The snippet of subscription code can be placed after module and class definitions in each .ts file so you can do what you need. TypeScript will just copy this JS to the resulting .js file.

In case of any questions, something interesting, another take on the same problem > please share in comments, thank you.

Download link : sample app