LINQ FirstOrDefault implementation in TypeScript

Proust looking of of the window thinking about LINQ operators

Confession: when working in JavaScript languages I kind of miss some C# things such as LINQ. A substantial part of my C# coding seemed to be chaining LINQ operators together. So rather than staring wistfully out of the window  in remembrance of things past – I thought I would just try to write one of my own. I’ve picked FirstOrDefault for this honour.

FirstOrDefault

For the uninitiated FirstOrDefault is a LINQ operator in C# that takes a function which resolves to a boolean – a predicate. It has the following characteristics

  1. Returns the first object in a collection that matches the predicate
  2. If it can’t find one then it will return null
  3. It won’t throw an exception if it can’t make the match – in contrast to it’s harsher sibling SingleOrDefault that will

TypeScript

I’m writing this In TypeScript – simply because that’s what I’m using at the moment. It would actually be easier to do this in plain JavaScript – the prototype will be the same and they would be no steps to hook it into the TypeScript interface. But we will do it in TypeScript

Implementation

Step 1: Extending Array Type

In C#, the LINQ operators are an extension of IEnumerable<T>. In TypeScript we will extend the Array object which is a similar principle. In Typescript type definitions go in .d.ts files. I’m working in Angular and there is handily a definition file already present – typings.d.ts. In that file put the following

This adds a firstOrDefault defintion to the Array type. It takes a function just like the C# first or default method. As we are using TypeScript we can specify a type of function for the parameter so we will get compile errors if we try to supply anything else to this method. Of course there is no implementation yet ….

Step 2: Implementing the LINQ operator

Create a file e.g. Linq.ts and enter the following

This method is going to do the work – it’s the meat and potatoes. We are leveraging the reduce operator. Reduce flattens a collection into a single value – a simple example would be totalling all the numeric values in an array i.e.

For us flattening the array means returning the first value that matches the predicate. So we iterate through until predicate(currentValue) evaluates to true then we stash the value in the accumulator object and once there we never write over it.

An interesting quirk to this is what happens on the first loop – if we call it like this

i.e. reduce with a single argument. In the first iteration the accumulator has the value of the first object in the array; the currentValue has the second. The first item is already stashed in the accumulator and the predicate is never checked – the first item is always returned no matter what the filter is. This is exactly what we don’t want. We need to supply a second argument to reduce …..

By supplying a second argument we specify what the initial value of the accumulator is. We want a initial value of null so our LINQ operator will attempt the match each time until it succeeds.

As a side note – I’m aware that there are any number of ways to achieve this but I’ve a theory that all of the LINQ operators can be done with JavaScript reduce, map or filter methods so this is my first step to prove that theory out. It can be done and it will be done (if I get the time).

Step 3. Consuming the LINQ operator

Import the linq prototype and use thus

This returns the first object in the array with an Id of 1. This compares quite nicely with the C# FirstOrDefault method which is

Which looks pretty similar to me and works in the same way. It doesn’t do a great job with type checking though and since we are using TypeScript we can do a bit better.

Implementation with Generics

We can use generics in TypeScript to get type checking in the predicate and get a typed returned value. An improvement I think.

Step 1: Extending Array Type

Go to the d.ts file again and use this

Which defines a function that takes type T and returns a boolean – our filtering predicate.

And a generic array extension which uses the typed predicate instead of the more generic Function type.

Step 2: Implementing the LINQ operator

Change the implementation to this

Which uses the generic types throughout.

Step 3. Consuming the LINQ operator

If we were using a collection of persons, the new generic powered firstOrDefault would be called like this

We can now get decent intellisense when filling in the filter conditions and type checking so we don’t compare the wrong types. It’s slightly more verbose than the first example but safer to use. I prefer it, but use whichever floats your TypeScript boat – both work.

Useful Links

https://codepunk.io/extending-strings-and-other-data-types-in-typescript/
More detail about extending built in types in TypeScript

https://danmartensen.svbtle.com/javascripts-map-reduce-and-filter
Nice comparison of the map, filter and reduce methods in JavaScript and guidance about which to use when.

https://www.tutorialspoint.com/linq/linq_query_operators.htm
Overview of LINQ operators. There’s more than you think.

https://stackoverflow.com/questions/7192040/linq-to-entities-vs-linq-to-objects-are-they-the-same
When I’m talking about LINQ I’m really talking about LINQ to objects. There is LINQ to SQL, LINQ to entities, LINQ to XML etc.. This SO question points out the difference.

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/query-syntax-and-method-syntax-in-linq
There are two styles of operators in LINQ – lambda and query syntax. Query syntax is

And the equivalent lamdba is

I’m emulating the lamdba syntax here. I never use the query syntax – I think it was easy route to LINQ for people more familiar with SQL. The lamdba is a more functional approach and nearer to what the code is actually doing. Anyway the query operator was only ever a sub set of the lamdba.

Getting the Root Directory Path for .Net Core Applications

Quick one. Given any .Net app I want to know the root path of the application i.e. the top level directory. I was doing this with .Net Core but it puts in extra directories by default in the exe path i.e.

bin\Debug\netcoreapp2.0\my.dll

so my normal kuldgy methods weren’t working. This all works for any .Net app not just Core in fairness – it’s just that the extra stuffed in by .Net Core threw me a little. There are all kinds of ways to find this for particular applications web, windows etc.. but this should work generally. Well it worked with my little console app anyway.

The Code

Use reflection to targeting the executable and get the path

this will get you

file:///c:/development/MyApp/bin/Debug/netcoreapp2.0/myApp.dll

which is the UNC path. Combine with Path.GetDirectoryName i.e.

this gets

file:\c:\development\MyApp\bin\Debug\netcoreapp2.0

which is a  file path now and it has got us the directory of the executable. It’s still not where we want to be so use some regex

This will chop up the path and gives you

c:\development\MyApp

which is correct.

The Function

So overall a useful function for this could be

Which does what we need or I quite like it as a (much abused) extension method

Which can be called like

Which gives

c:\development\MyApp\TargetFile.cs

Job done.

The Regex

Not everyone likes Regex*. But for the aficionados here is what it is doing

For example matching this

file:\c:\development\MyApp\bin\Debug\netcoreapp2.0

Is my match – this will match a drive and a path up to

It’s a lookahead (zero length assertion). It will check for “bin” but not include it in the match

It’s a negative lookbehind (zero length assertion again). It will make sure that the letters fil don’t immediately proceed the match. This is to stop e:// being the match i.e. the e from file.

Clearly this assumes that the bin folder is directly under the root path as it normal is. If it isn’t in your app then break out your favourite Regex editor and write your own. It will make a man/woman/scared child of you.

(* Hardly anyone likes it – well I haven’t met many)

Useful Links

https://stackoverflow.com/questions/837488/how-can-i-get-the-applications-path-in-a-net-console-application
Full disclosure – the first bit of this is from this SO question. The extension I did with my very own coding fingers

http://regexstorm.net/tester
Regex storm – C# regex tester. Very good. JavaScript based testers don’t work with this as they can’t do negative lookbehinds.

https://www.regular-expressions.info/lookaround.html
Look ahead, behind and all around with zero length assertions

Passing Parameters with Automapper

OK I admit it – sometimes I find automapper hard to work with. It’s fantastic when everything is well … auto, but some of the mappings I work with on a day to day basis are anything but automatic. There is not much auto about the automappings. But enough of my troubles – one of the lesser known features of automapper that I have found useful is the ability to pass parameters around. This allows you to implement mappings that are dependent on some other part of the object graph; a part that is not normally accessible in the context you are working with.

Example

For a demo I have a simple application that retrieves customer who have visited my lovely shop. I retrieve customer database entities and I want to map them to some DTOs. Just for the example we will display the object on a console application – I’m not concerned with the UI right now so this is good enough. I guess I missed the UI design parts of my university course. I must have slept in that day.

Database Entities

The customers object that we retrieve from the database are

This is just a straight representation of our database. It’s a customer of a given type with an address. Too easy.

DTO message

As is very standard we want to map the database entity to a set of DTOs. These are

The Problem

We want the residential property on the address DTO to be false if the customer type is business but true otherwise. So let’s try that.

Constructing the mappings

Mapping an object with no parameters

So our first mapping is very straightforward

We are letting the automapper magic do its thing. HouseName maps to HouseName, Street maps to Street and so forth. It all looks very good.

However if I retrieve a customer that I know is residential then the residential property of the customer object isn’t set. The output of my mapping is

map-no-parameters

The residential property is false. This makes sense – I haven’t mapped

to anything. In fact my mappings aren’t really valid at all. If I check the mappings in code with

It will throw an exception with the message

Unmapped members were found. Review the types and members below.

Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type

For no matching constructor, add a no-arg ctor, add optional arguments, or map all of the constructor parameters

==============================================================

Address -> AddressDto (Destination member list)

Automapper.Entities.Address -> Automapper.Messages.AddressDto (Destination member list)

Unmapped properties:

Residential

This tells me exactly what my issue is. The valid mapping is

And my full code for this is

Which has the same output as before but this time is actually valid.

map-no-parameters

How can I set the residential property? The problem is that I need information from the customer object when the address object is being mapped. However when I am mapping the address object I’m in the context of the address and I don’t have the customer information. I can’t do the mapping.

Mapping an object with parameters

What I want to do is pass information from the customer into the address mappings. I’m going to use parameters for that. The call to map has a ResolutionContext. This has dictionary object that I can use to pass through information i.e.

So when I call the mapper I can pass what the customer is using the overload with ResolutionContext

So now the context knows what type of customer this is. I need to grab the context in the address mappings. Happily there are several hooks into the resolution context I can use within the mappings. For this I’m going to use a custom value resolver

The interesting part of the code is

I am using a resolver to access the information in the resolution context and set the residential property using this. It works and the residential property is set correctly

map-with-parameters

However, I am relying on passing the information myself into the mappings. If I forget to pass in CustomerType then the mapping collapses with a null exception. Also I want these mappings to use the full automapper goodness and be able to map lists of customer entities into list of customer DTOs. It’s not going to do it.

Mapping lists of objects with parameters

To map lists of objects I want the mappings to set the context themselves. That going to be good as it will hide this away from consumers of the mappings and avoids mistakes. I’m going to use the BeforeMap function which also has an overload for ResolutionContext.

As the name implies it runs before the mapping takes place so it’s a good place to set up the context. So the call to the mapper becomes

End consumers no longer need to worry about the context; it just works. We can use the amended code to map lists of objects i.e.

map-list-with-parameters

The residential property is set correctly for each object in the list. Job done!

Demo Project

Full source code for this post is on github at
https://github.com/timbrownls20/Demo/tree/master/AutoMapper

Useful Links

Automapper
https://github.com/AutoMapper/AutoMapper

Worked example of automapper custom value resolvers
https://automapper.codeplex.com/wikipage?title=Custom%20Value%20Resolvers

ToStringBuilder
To output a string representation of the object to the console I used a nifty bit of code on stack overflow to create a generic ToString method for objects. Nice!
http://stackoverflow.com/questions/2417647/is-there-an-equivalent-to-javas-tostringbuilder-for-c-what-would-a-good-c-sha

 

Handlerbars.js and Working with Complex Objects in MVC

In a previous post I used an EditorFor template to display child objects correctly on a view. Now we are going to use some simple JavaScript templating to add child objects. We have a page display book details and want to add and save additional authors.

Demo app

The demo app is a simple bookshelf application. It has a view that uses EditorFor templates to display a book which we want to save. The book can have multiple authors. It is a complex object.

The book is rendered onto the Book.cshtml view and the user sees a book then can be edited and saved as required.

authors-correct-display

The authors are rendered in this format

When this form is posted back, the default model binder in MVC uses the name attribute to correctly bind the authors as a child object of the book object. So we get a correctly populated book object passed through to the controller action.

The book parameter is populated will the correct authors. Nice. In general, to work with child objects the correct format for the name attribute in the HTML form element is ..

We’ll need to bear that in mind when we are creating a control to add new authors.

The Problem

The authors display correctly and work well but what if we want to add additional authors to the book before saving? Perhaps the book is missing authors. Perhaps I’m a rampant egotist and want to add myself as an author to every book in my virtual bookshelf. Let’s use Handlerbars.js and some JQuery goodness to do this.

The Solution

Handlebars.js

Handlebars.js is one of many JavaScript templating engines that bind fragments of HTML and produce data driven templates. Handlebars takes a template such as

And binds it against some JSON

To produce HTML

That’s going to be good for us. We’ve got some pretty chunky fragments of HTML and we want to work with it in the cleanest way we can.

Integrating Handlerbars.js into MVC

Install the package using nuget

In it goes to the application. Now create a script bundle in BundleConfig.cs

and reference that bundle in the view

Creating the HandleBar template

Let’s dive straight in and create the template. We want a HTML fragment that will generate us a new author. HandlerBar templates need to be in script tags with the type

our full template is

This gives us a hidden field for the AuthorID and a text field for the author name. The curly brackets tell us where the holes in the template are so

Are the two pieces of data that the template needs. Handlebars will replace these with the data we supply it.

Constructing the Author add control

Now we need a HTML control to add the author. We want something like this

authors-with-add-button

So a textbox and a button with a squirt of CSS

Let’s assume that JQuery is already reference and available. Next job is to wire up the click event to the button

Which is standard stuff.

Obtaining the data for the template

Next we need to construct the JSON data that Handlebars will use to generate the HTML. We need two pieces of information

  1. The authors name as inputted by the user
  2. The next index of the author elements

Grabbing the author name is straightforward

However to get the next index we need find the current highest index. First we need to navigate the DOM to find the last author. The authors are all wrapped in the ‘shelf-authors’ class to facilitate this

then we want the name attribute

Then we want the last index. If there are 3 authors then lastAuthorFormName will contain

So some regex the current index i.e. the number in square brackets

The entire regex matches “[2]” and the first and only group (\d*) matches the digit itself. The output for this is an array. The first element of the array is the full match. All subsequent elements are the matches for the containing groups (defined in regex by parenthesis). So

would equal “[2]” and

would equal “2”.  So to get the next index we need

Now we have all the information we need to construct the data for the handlebar template

Gluing the template together

Gluing the data into the template is pretty much boilerplate code

Grab the template with a CSS selector then compile and combine. The HTML is now correct and can be inserted into the DOM

The Complete Solution

So combining all the steps together we get

The HTML element is now correct and when this is posted back the new author will be present in the action method i.e.

The book parameter will have a fourth author which will be saved.

author-successfully-added

So I can now add myself as an author to every book in my library which goes some way into feeding my monstrous and uncontrolled ego – which is what it’s all about really.

Useful Links

Project page for handlebars
http://handlebarsjs.com/

Nuget page for handlebars
https://www.nuget.org/packages/Handlebars.js/

Demo application source
https://github.com/timbrownls20/BookShelf/

 

ASP.Net MVC and Binding Complex Objects Magic

I’ve a habit of declaring things magical when I don’t fully understand how they work and haven’t the time to look into them any further. One of the things I’ve often declared magical is model binding with MVC. It just works. Magical.

Recently though I found model binding with child objects a bit on the difficult side of things. The magic was failing to sparkle correctly and needed a little bit of extra developer sprinkles to work. Perhaps it even needs developer understanding.

Demo Application

I’m going to demonstrate the problem and solution using a demo library application. The application queries Google Books API and allows users to edit and add those books to their own virtual bookshelf. The book shelf app can be found here

https://github.com/timbrownls20/BookShelf/

 Workflow

The relevant part of the application is adding of books to the library. The work flow is …

  1. User searches for a book
  2. Application queries GoogleBooks and displays a list of matches
  3. User selects a book
  4. Application displays the selected book.
  5. The user amends the book record as required
  6. The application saves the book

So once the user has typed in a search term they are presented with a list of books which they can select.

book list
Save.cshtml

Once selected a view showing the detail of the book is present to the user. The user is invited to save the book into his or her book shelf.

authors-incorrect-display
Fig 2: Book.cshtml

The problem is that the authors are not saved correctly. It’s pretty obvious that the authors aren’t displayed correctly. The HTML output looks fairly nonsensical.

We are going to have to dig into the application a bit further to fully understand this.

The Model

The model of the application is

So a book can have multiple authors. It is a complex object. It is the complex object and how that is rendered on the Book.cshtml view that causes us the problem. When it is posted back the book object lacks authors. The binding of the complex model has failed.

Book Create Action

When the user selects a book from this list this action is called. It displays the book ready for a save. We pass in an id (from the list selection) then the service goes away and grabs the full details of the book.

The book is then displayed on the view Save.cshtml. The user presses submit which posts the book back to the server.

Book Save Action

This action is called when the user saves a book to his or her bookshelf. The posted back book is saved.

This action takes the book object and it is here that we want form data to bind and produce the complex object. We want the model binding to produce the book object as a parameter. We want the magic. The magic fails us.

The Problem

It doesn’t just magically work much to my disappointment. What is displayed is not helpful.

authors-incorrect-display
Fig3. Book.cshtml with incorrect author display

Posting this page doesn’t binding the child object and the authors aren’t there. The HTML is just not there. So how can I easily, and with as much magic as possible, change the view so that the authors are present and the form elements are named correctly? What does the default model binder actually want and how can I provide it?

The Solution

EditorFor Templates

The view needs to know how to display the author object. I could loop through in in the view but a better solution is the EditorFor template.

In View/Shared/EditorTemplates create a file called Author.cshtml. By convention MVC will find this and use it to display the Author property. We are telling it what to write out when the author property is edited i.e. what HTML to write out when the following call is made in the view

The Author.cshtml is pretty simple

The Corrected View

Now this is in place the view looks a lot better and it works.

 

authors-correct-display
Fig 4. Book.cshtml with corrected author functionality

When save is pressed the full object is passed to the Save Action and the object included authors can be persisted

What is interesting is the rendered output. Viewing the page source (stripping out the validation data elements, styling etc..) we see this

So the convention that the default model binding requires is revealed. I wouldn’t have just guessed it but the EditorFor Template does it for us.

Although both the id and name look like reasonable candidates for model binding, it is the name attribute that is used. The format for child objects is

so more complex objects are perfectly possible

and so on until you gone down a complex rabbit hole of 7 nested objects from which you might never return.

Adding New Authors (child objects)

One of the things we might want to do is enable a user to add new authors. Perhaps the retrieved book doesn’t have all the authors and the user is a stickler for detail. Knowing the required format of the child object html is going to help us with that. In its very simplest form it could a bit of jQuery based on this idea

But we would need to bit cleverer, use templating, work out the next index etc… But this gives us the starting point to be able to provide that functionality. An exercise for another day perhaps.

Note
I’ve now implemented a solution using Handlebars.js to add authors into the complex object. See this post for details.

DisplayFor Templates

As an aside we could/should also do a template for displaying a read version of the model i.e. when the following call is made in a view.

It’s not needed to get this to work but it seems like a generally good and wholesome thing to provide this as well. The display template can be very simple..

 Useful Links

More detail about EditorFor and DisplayFor templates
http://www.codeguru.com/csharp/.net/net_asp/mvc/using-display-templates-and-editor-templates-in-asp.net-mvc.htm

Some more insight into how complex data binding works
http://blog.codeinside.eu/2012/09/17/modelbinding-with-complex-objects-in-asp-net-mvc/

How to manipulate the DOM through JQuery which we would need to dig into a bit to implement adding an author
http://api.jquery.com/category/manipulation/

Google Books API reference in the blog post
https://developers.google.com/books/