Wednesday, December 13, 2017

Lettable operators in RxJs

After upgrading to Angular 5 (and having some trouble with RxJs but that is for another post), I noticed the introduction of "lettable operators", which can be accessed in rxjs/operators.

What is a lettable operator?

A lettable operator is basically any function that returns a function with the signature: <T, R>(source: Observable<T>) => Observable<R>. Euhm, what?!

Simply put, operators (like filter, map, …) are no longer tied to an Observable directly but can be used with the current let operator(explaining the name). This means you can no longer use the dot-chaining, but will have to use another way to compose your operators.

Therefore is a pipe method built into Observable now at Observable.prototype.pipe:

Why lettable operators?

Lettable operators were introduced to solve the following problems with the dot-chaining(from the documentation):

  1. Any library that imports a patch operator will augment the Observable.prototype for all consumers of that library, creating blind dependencies. If the library removes their usage, they unknowingly break everyone else. With lettables, you have to import the operators you need into each file you use them in.
  2. Operators patched directly onto the prototype are not "tree-shakeable" by tools like rollup or webpack. Lettable operators will be as they are just functions pulled in from modules directly.
  3. Unused operators that are being imported in apps cannot be detected reliably by any sort of build tooling or lint rule. That means that you might import scan, but stop using it, and it's still being added to your output bundle. With lettable operators, if you're not using it, a lint rule can pick it up for you.
  4. Functional composition is awesome. Building your own custom operators becomes much, much easier, and now they work and look just like all other operators from rxjs. You don't need to extend Observable or override lift anymore.

In short lettable operators will improve tree shaking and make it easier to create custom operators.

Tuesday, December 12, 2017

PostgreSQL: Identify your slowest queries

PostgreSQL provides a large list of modules that extends its core functionality. One of these modules is the pg_stat_statements module that provides a means for tracking execution statistics of all SQL statements executed by a server.

Before you can use this module, it must be loaded by adding pg_stat_statements to shared_preload_libraries in postgresql.conf, because it requires additional shared memory. This means that a server restart is needed to add the module.

After loading the module you can execute the below query to get the top 5 duration queries executed during your performance/benchmarking run:

It is recommended to reset the pg_stat_statements using the query below to ensure that you only capture the statements from your performance/benchmarking run:

Monday, December 11, 2017

System.Data.SqlClient.SqlException : The ntext data type cannot be selected as DISTINCT because it is not comparable

After upgrading to NHibernate 5, one of our integration tests started to fail with the following error message:

System.Data.SqlClient.SqlException : The ntext data type cannot be selected as DISTINCT because it is not comparable.

The error itself happened inside a by Nhibernate generated query:

Message: NHibernate.Exceptions.GenericADOException : [SQL: select distinct supplier1_.SupplierID as supplierid1_138_, supplier1_.Address as address2_138_, supplier1_.City as city3_138_, supplier1_.CompanyName as companyname4_138_, supplier1_.ContactName as contactname5_138_, supplier1_.ContactTitle as contacttitle6_138_, supplier1_.Country as country7_138_, supplier1_.Fax as fax8_138_, supplier1_.HomePage as homepage9_138_, supplier1_.Phone as phone10_138_, supplier1_.PostalCode as postalcode11_138_, supplier1_.Region as region12_138_ from Products product0_ inner join Categories category2_ on product0_.CategoryID=category2_.CategoryID, Suppliers supplier1_ where supplier1_.SupplierID=product0_.SupplierID and category2_.CategoryName=@p0] 

The error message pointed us to a ntext data type. A look into the database revealed that indeed we were using the ntext data type.

clip_image002

It is recommended to avoid this data type(it is marked as obsolete) and use nvarchar(MAX) instead.

But why didn’t we got this error before? It turned out that the query generated by NHibernate 5 is different then the one used by NHibernate 4. In NHibernate 5 an extra DISTINCT clause is added to the query, resulting in the error message above.

Friday, December 8, 2017

Angular 5 - EmptyError: no elements in sequence

After upgrading to Angular 5, the first run of my application ain’t a big success. I ended up with the following error message when I tried to navigate using the Angular Router:

EmptyError: no elements in sequence

The problem turned out not to be related to Angular directly but to RxJS 5.5.3. Reverting to 5.5.2 resolved the problem.

npm install rxjs@5.5.2

More information: https://github.com/angular/angular/issues/20752

Thursday, December 7, 2017

Angular Update Guide

With the fast cadence that new versions of Angular are released, it is not always easy to know what steps are necessary to go from one version to another.

To help you, you can use the Angular Update Guide: https://angular-update-guide.firebaseapp.com/.

This is a small application that asks you the following questions:

  • From what version to what version do you want to migrate?
  • How complex is your app?
  • Do you use ngUpgrade?
  • What Package Manager do you use?

image

After answering all these questions, you can click the Show me how to update! button and you get a step by step guide:

image

Wednesday, December 6, 2017

NHibernate 5–Async/await

With all the fuzz about .NET Core I almost forgot that NHibernate 5 was released a month ago.

One the things I was waiting for was the introduction of async/await to optimize IO bound methods. And after waiting for a loooooong time it’s finally there:

Tuesday, December 5, 2017

TypeScript: Variable 'require' must be of type 'any', but here has type 'NodeRequire'.

After loading a solution for a code review, I was welcomed by the following error message:

Variable 'require' must be of type 'any', but here has type 'NodeRequire'.

Google brought me to the following GitHub issue; https://github.com/Microsoft/TypeScript/issues/16298 where the proposed solution was as simple as beautiful:

There must be another definition of require somewhere.

And indeed, after triggering a search on my solution I found another ‘declare var require’ somewhere in a typedefinition file. After removing it, the error disappeared (and everything still worked).