Search After Stop Typing React Component

In this post I’m going to go through how to implement a search criteria component that only invokes the search in a calling component after the user has stopped typing.

So, we have the following search criteria component that invokes the search on a submit button at the moment:


… and this component is referenced like the following in a calling component:

At the moment, our submit button triggers the form’s submit which in tern calls handleSubmit() which then calls this.props.doSearch in our calling component to invoke the search (our calling component actually does the search).

Here’s what our component looks like at the moment:

We want to remove the submit button and just have the search invoke when the user stops typing.

So, let’s first remove the form and submit button from our render function:

Now let’s just invoke the search in handleCriteriaChange after we have set the criteria in the state:

So, our component invokes the search on every keystroke that the user does:

Not quite what we want!

We need to “debounce” the search. That’s where the debounce function in the excellent lodash library comes in.

So, let’s bring lodash and the TypeScript types into our project:

We now need to import just the debounce function into our component:

If we look at the docs, debounce just creates another function that delays calling another function. So, let’s create our “debounce” function leaving the console.log() so that we can check that doSearch is only being called when the user has stopped typing:


… and let’s call our new function from handleCriteriaChange:


… and let’s give this a try:

… which is just what we want!

Here’s the full code for our debouncing search criteria component:

Connect with me:RSSGitHubTwitterLinkedIn

Formatting dates and numbers in React

Formatting numbers and dates is a common requirement for lots of apps but how do we do this in react apps?

Let’s say we have a component in our app that shows a list of customers, looking like this:

… and here’s the current code for this component:

… with the following data:

You can see that we need to clean up the revenue and first sale data by formatting them.

Formatting numbers

We can use Intl.NumberFormat to format the revenue:


In the above example we are formatting to revenue using Great British locale, using the Great British currency style.

So, we now have this:

But what if we don’t want the decimals in the revenue? We just add the min and max fraction digits in the options:


Formatting dates

We could just use toLocaleDateString instead of toString:


… which gives us a nice short date:

However, we can use Intl.DateTimeFormat to gain more control on the formatting:


Here we are specifying a 2 digit day, a long month and a 4 digit year.

So, here’s our final CustomerSearchResults component code:


… and here’s what it looks like:

Much better!

Connect with me:RSSGitHubTwitterLinkedIn

Building a simple component in React.js v2

I’ve been using React again recently. It’s come along way in the last couple of years since I last blogged on building a simple search component. In this post I’ll build this component again using TypeScript with modern React constructs …

This is a link to the old code and below is what it looked like:

Getting started

To scaffold the app I used TypeScript-React-Starter.

The key steps are installing create-react-app …


… and then running it, referencing some TypeScript scripts …


You can then use the following command to start the app …

Basic component structure

The app is going to consist of the following components as we had in v1:

  • Criteria – responsible for the display and entry of the search criteria
  • ResultsList – responsible for the display of the search results
  • Search – this wraps the Criteria and ResultsList components and performs the actual search
  • App – the top level component for our app (essentially just wrapping the Search component)

Criteria component

Let’s start with our Criteria component …

This is a functional component with no state.

It takes the current criteria value in as a property which is then bound to the criteria input value.

It also takes in a delegate function in as a property which is bound to the form’s submit event via our handleSubmit() function.

Finally it takes in a delegate function in as a property which is bound to the criteria input change event via our handleCriteriaChange() function.

We are also using the arrow function notation to avoid the “this” scoping problem.

ResultsList component

Let’s move on to our ResultsList component …


This is also a functional component with no state that takes in the customers to display as a property value.

We make use of Array.prototype.map() to project the customers into a html list.

We also need to remember to include the key attribute so that React can properly manage changes to the html list.

The interface for Customer is:

Search component

Now on to our Search component …


This is our first component which has state which is why we are using a class component. Our state consists of:

  • allCustomers – a hardcoded array of all our customers
  • filteredCustomers – the current array of filtered customers
  • criteria – the current criteria

The state is intialised in the constructor with the filtered customers set to all the customers and the criteria set to an empty string.

The handleCriteriaChange() function catches changes to the criteria that are bubbled up from the Criteria component and sets the criteria bit of the state.

The doSearch() function catches the submit event from the Criteria component. It then does the appropriate filter on the array of customers using Array.prototype.filter(). Lastly it sets the filteredCustomers bit of the state.

The markup simply references the Criteria and ResultsList components, passing the appropriate properties.

App

Lastly, here’s our App functional component which simply wraps the Search component …

That’s it! The code certainly feels a lot cleaner than v1.

Connect with me:RSSGitHubTwitterLinkedIn

Fluent Validation in an ASP.NET Core Web API

Fluent Validation allows you to separate validation rules from your model and helps you structure the rules so that they are nice and readable. The rules are also super easy to test.

Some existing code

Let’s say we have started to build a web api to add new customers:


Our NewCustomer model is:


We also have an action filter which will handle validation on the models and return a 400 if they are invalid:


Startup.ConfigureServices looks like this to wire everything up:

So, let’s say we want to make CustomerName a required field in the POST method on the newCustomer model. We could use a standard data annotation:

However, we’re not going to do this. Instead, we’re going to use Fluent Validation to keep our validation logic separate from the model and go on to add more complex rules …

Getting started with Fluent Validation

First we need to bring this library in via nuget. The packge that needs adding is FluentValidation.AspNetCore.
We can then wire this up in Startup.ConfigureServices by adding AddFluentValidation() to AddMVC():


Now let’s add a validation to ensure CustomerName is populated on the newCustomer model using the power of Fluent Validation:


As you can see, this rule is nice and readable. This class is also picked up automatically with the work we have already done in Startup.ConfigureServices.

To check this is working, let’s try to POST a customer without a surname to our API – we should get a 400 with a nice error message in the response body:

Adding some more simple rules

There’s quite a few built in rules in Fluent Validation, including a rule to validate an email address. So, let’s use this:


We can also add multiple rules on a field. Let’s add minimum and maximum length rules on CustomerName:


Again, this is nice and readable.

Conditional rules

So far the rules have been nice and simple. Let’s deal with more complex rules, starting with conditional rules. For example, a rule to ensure the first name is populated if the customer type is a person:


As well as implementing this rule, we’ve also made CustomerType a required field.
What about controlling the error message? At the moment we just get:
‘First Name’ should not be empty.
Let’s change the message to:
‘First Name’ must be filled in for customers of type ‘Person’.
All we need to do is chain a WithMessage() on the rule:

Custom rules

Lastly, we’ll look at a custom rule to ensure the company type is “Person” or “Company”. The rule will be called ValidCustomerType and invoked like below:


We define the rule like so:


We also need to define this validator in a static class (along with any other custom rules):

Unit tests

I introduced this post by saying how simple these rules are to test. The following tests are a few we could write against CreateCustomerValidator using Fluent Validation helpers ShouldHaveValidationErrorFor and ShouldNotHaveValidationErrorFor:

Conclusion

As you can see Fluent Validation is a great library for creating validation rules outside your model. I’d encourage you to check out the project on Github.

Connect with me:RSSGitHubTwitterLinkedIn

Creating a Multi-Tenant ASP.NET Core Web API with SQL Server RLS

In this post we’re going to leverage SQL Server Row Level Security (RLS), Entity Framework Core and ASP.NET Core to create a multi-tenant database with a multi-tenant web API …

First, let’s create a database containing a couple of tables – one to hold our tenants and one to hold some real data (products in this example):

We’ll add some test data in there as well. We’ll have 2 tenants – one with 3 products and the other one with 2 products:

Before we move on to RLS, let’s create a “super user” that will have access to data in all the tenants (this is useful for debugging). While we are at it, we’ll create a “normal user” that our web API will use to access data:

Now on to the RLS. First we need to create a predicate function that is going to apply a filter when the product table is accessed for the given tenant. The tenant for a given row is passed into the function. The tenant that the API is operatoring for is stored in SESSION_CONTEXT('TenantId') – we’ll come on to how this is set in the web API soon. We also need to make sure our super user has access to all the rows in the table

Now we can bind our predicate function to our product table. The FILTER predicate ensures we only read data for a given tenant and the BLOCK predicate ensures we only write data for a given tenant:

So, let’s give this a quick test, connecting as normaluser:


We should get following results back (3 rows for the first query and 2 for the 2nd query):

If you connect as superuser, SELECT * FROM dbo.Product, you should get all 5 rows.

Cool, we’re done with our database. Let’s move on to our web API …

Let’s create a new ASP.NET Core Web Application in Visual Studio, choosing the Web API project template.

First let’s create our model classes to hold our tenants and products …

Now, we’ll bring in EF core using nuget (I’m using the stable 1.1.2 packages). We’ll need Microsoft.EntityFrameworkCore and Microsoft.EntityFrameworkCore.SqlServer.

Time to create our EF core data context. Here’s a basic class that maps our tenants and products:

We’re not done with DataContext yet – we need to set SESSION_CONTEXT('TenantId') for every query that EF core does … we’ll come back to this after we’ve got the tenant from the API.

So, let’s create some middleware that will inspect the API key from the request to determine the tenant:


Please note the highlighted line in the above code where we place the tenant in a dictionary in the HttpContext. This is how we are going to get the tenant in DataContext.

Before we go back to DataContext, let’s go and do all our registrations in Startup:

Time now to go back to DataContext.
We can set the tenant in our constructor:

We can then set SESSION_CONTEXT(‘TenantId’) every time a connection is opened before any queries are run by EF core.

Ok, we’re done with DataContext now. Let’s create a simple API now to get some products:

Let’s check this is working in Postman with our 2 API keys. We should get 3 products for the 1st key and 2 products for the 2nd key:

Cool, we are good. Let’s quickly add an action method to get a product by its id:

Now let’s create the action method in our API to post new products:


… and let’s give it a try:

… it blows up!

We obviously have a problem because we are not submitting the tenant id in the product.

I lied when I said we were done with our database! Let’s add a default value for the tenant id that picks up SESSION_CONTEXT(‘TenantId’):

Now, when you post a product in Postman, we should be ok:

To finish off our controller we’ll quickly implement a PUT and DELETE:

Pretty straightforward and they both work. If you try to PUT and DELETE products that belong to a tenant that your API key is not for then you get a 404 – just as we want.

The great thing about this approach is that there is no reference to the tenant in our controller code – the multi-tenancy is taken care for us lower down in the stack which reduces our development costs and risk of leaking data.

Connect with me:RSSGitHubTwitterLinkedIn

HttpContext in ASP.NET Core

HttpContext is largely the same in asp.net core as it’s always been. However, one difference is that it is not automatically as available everywhere in your code base as it used to be …

If you are in a controller then you are okay – HttpContext is a property of ControllerBase:

If you are in middleware then you are okay – HttpContext is passed in as a parameter:

However, if you are in the domain layer, the you need to do some work …

First you need to register IHttpContextAccessor for dependency injection in the apps Startup class:

In your domain layer, you then need to bring in Microsoft.AspNetCore.Http via nuget and use dependency injection to get a reference to IHttpContextAccessor which in tern gives you a reference to HttpContext

Connect with me:RSSGitHubTwitterLinkedIn

Integrating Validation in Angular 2 and ASP.NET Core

I’m building an Angular 2 app with an ASP.NET core web API behind it and need to add some validation. Obviously, I need to validate on the server in the web API, but I also want to do some client validation to make sure the user experience is good …

Server Validation

Here’s my model, which you can see is using attributes to define some required field validation:

Here’s our controller below.

If the required fields aren’t filled in (detected from the attribute validation) a HTTP 400 status code is returned with the validation errors in the response body.

We also do some more complex validation, checking if the email address is already in use. Again we return a 400 and the validation error if the email address exists in our database.

So, let’s test our API in Postman.

Test that required fields are validated:

Test that a valid person is saved:

Test that a person with an email address already in the database is validated:

Wiring up our Angular 2 app

Now, that we have our web API in place, let’s build our page to submit a new person.

At this point we’re not going to implement any clientside validation – we’re just going to handle the validation coming from the server.

Here’s our component markup:

  • Lines 1-7 will show the validation errors from the server
  • Lines 8-10 will show confirmation that the person has been saved into the database ok
  • Line 12 defines our form, telling angular that the form object will be called personForm and submit handler will be a function called onSubmit
  • Lines 14-46 define our field inputs for the person
  • Lines 48-52 defines our submit button

Here’s our component code:

  • Line 14 defines a variable called errors which will be an array of validation errors
  • ngOnInit on line 19 creates our form object with no client side validation defined at the moment
  • onSubmit posts the person object to our web API. You can see we catch validation errors on lines 47-55, pushing them to the errors array

If you run the app and hit the Submit button without filling in the inputs, you get something like:

Client Validation

Now, let’s implement the client validation in the angular app.

First, we need to change ngOnInit to include the validation rules:

Then, we need to change our markup for the field inputs to output the validation errors. Here’s the markup for the title input:

  • Line 1 adds the has-error CSS class if we have touched and not filled in the input
  • Lines 13-16 displays the error message beneath the input if we have touched and not filled in the input

So, cool, if the user doesn’t fill in any of the inputs, validation errors will be shown before the submit button is pressed:

However, what if we enter a duplicate email address:

As you can see, the validation error from the server is shown which is good, but ideally we want to highlight the email input and display the error beneath it. So, we need to integrate our validation errors from the server into Angular’s validation.

The solution is in the highlighted lines below. We know the field name from the server’s validation error dictionary. So, if the field is on our form, we flag to angular that there is an error using the control’s setErrors function.

In our example, we don’t have any validation that is not bound to a single field (cross field validation), but if we did, the validation errors would be shown at the top of the page.

Now, if we try to input a duplicate email, our user experience is much nicer:

If you want to learn more about making Angular and ASP.NET core work well together, I’d recommend reading ASP.NET Core and Angular 2

Connect with me:RSSGitHubTwitterLinkedIn

Testing EF Core Repositories with xUnit and an In Memory Db

I came across the EF Core In Memory database recently. It obviously won’t have all the features of a relational database but it might be useful when unit testing simple repository methods.

Let’s take it for a spin …

Starting point

We have the following repository that we want to test. We’re just going to test the Add method in this post:

Here’s the EF data context and models behind our repository:

xUnit

So, let’s bring in xUnit by adding the following entries into project.json:

We also need to tell Visual Studio that xUnit is going to be our test runner by setting the following as a root property in project.json as well:

Now we can start adding xUnit tests. Let’s just add a couple of simple tests to double check xUnit is wired up properly. Let’s add the following class containing a test that should pass and a test that should fail:

If we open up Test Explorer you’ll see our tests and if you run them, 1 should pass and should 1 fail.

As a bonus, you can also run these tests from the command line by browsing to the app’s folder and running the following command:

Again, you should see 1 passing and 1 failing test.

In Memory Database

Before we test our repository, let’s bring in the In Memory database into our solution by adding the following dependency in project.json:

Repository Tests

So, let’s start testing our Add method in our repository by creating a class and a method to test the storyline when a person has no email address:

GetInMemoryPersonRepository is a method that all our tests will use to spin up a PersonRepository containing no data. Line 26 tells our data context to use the In Memory database. Lines 29 and 30 ensures we have a new database with no data in it.

The test is straight forward. Lines 6-12 creates a repository and a person with no email address. Line 14 calls the Add method in our repository passing in the person. Lines 16-19 carry our checks.

If you run the tests, all should be good.

Now, let’s add a couple more tests to test adding a person with single and multiple email addresses:

The tests are straightforward, following the same structure as the 1st test, using GetInMemoryPersonRepository to spin up a PersonRepository with an In Memory database behind it.

If you run the tests, all should be good.

The tests are also quick – on my machine the three tests took 7, 13 and 624 ms.

Connect with me:RSSGitHubTwitterLinkedIn

Getting Started With EF Core Migrations

Entity Framework (EF) migrations are a way to modify the database through different iterations of the software. Let’s have a play with these in EF Core in a web API project …

Models

Lets start with the following simple models to hold data about people:

Adding Entity Framework

Now let’s add EF to our solution in project.json (I’m still using .NET core 1.0):

DataContext

Let’s add the following data context:

Wiring EF up

To wire the app up to EF, first let’s add the following line to Startup.ConfigureServices:

We then need to add the following line in appsettings.json:

First migration

So, let’s have a go at our first migration …

Open a command prompt, browse to your solution directory and enter the following command:

After a second or so, our first migration will have been created in a Migrations folder in our solution:

Let’s have a look in the *_init.cs file. Cool, I can see an Up() method creating the 3 database tables and a Down() method droping the 3 tables. So, we have code that is going to create our schema which we can nicely source code control.

Let’s have a look at the PersonDataContextModelSnapshot.cs. As the name suggests, this looks like a copy of the schema – to faciliate the next migration generation.

But what will the generated migration SQL look like? Go back to the command prompt and enter:


The SQL will be output to the screen (you can output to a file by using the command dotnet ef migrations script -o {filename}).

The script creates a table called __EFMigrationsHistory which I didn’t create in my model. This will hold the list of migrations. You can see it adding our *_init migration at the bottom of the script.

I like that the primary keys have been correctly implemented as identities in the script. I like the foreign keys … I’m not liking the varchar(max) all over the place though!

Let’s fix the varchar(max) problem by adding the following code into PersonDataContext which specifies table names, field lengths and required fields in our schema:

So, let’s see what the script looks like now. First we need to remove our last migration by entering the following command:


You’ll notice the Migrations folder is now empty in our Visual Studio solution.

Now run the following command to generate the new migration and output the SQL script:

That’s much better!

Creating the database

So, let’s create the database by running the following command:


After a few seconds, the database will have been created. You should be able to see the database in Visual Studio in the SQL Server Object Explorer

Second migration

Now, let’s implement a model change. We’re going to add a Created property to our Person model:

Let’s create that migration:

If you open up *_Person_Created.cs you’ll see the migration to add our new column.

Before updating our database again, let’s check our SQL migration script. We need to specify the migration we want to start from which in my case in 20170125045706_init:

This looks good.

Updating the database

So, let’s update the database by running the following command:


After a few seconds, the column will have been added to the database:

Connect with me:RSSGitHubTwitterLinkedIn

Getting the right version of TypeScript in a Visual Studio ASP.NET Core Project

I’m building an ASP.NET Core Angular 2 app. I think I’m using the latest version of TypeScript (2.1 at the moment) but I’m not sure …

If I open a command prompt and type:

it gives me:

So, great, my app must be using the 2.1?

Let’s check this by writing some 2.1 code:

Visual Studio complains straight away, putting a red squiggly line under the ...‘s. If you hover over the complaints, you get a tooltip saying “property assignment expected“.

Lets try running the app. It runs perfectly fine with mergedPerson correctly outputted to the console.

What’s going on? The visual studio compiler must be using a different version of TypeScript.

For classic ASP.NET projects, TypeScriptToolsVersion in csproj used to define the TypeScript version but that is no longer the case in ASP.NET core. In ASP.NET Core, this appears to be defined in a file called Microsoft.TypeScript.targets at C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v15.0\TypeScript:


So, this makes sense – Visual Studio appears to be using v1.8 (line 4).

Unfortunately, simply changing the 1.8 to 2.1 didn’t work for me.
I looked in my C:\Program Files (x86)\Microsoft SDKs\TypeScript directory. I only had a folder for 1.8.

Visual studio was obviously missing something, so, I downloaded and installed the latest version of TypeScript for Visual Studio.

Voila! The red squiggly lines disappeared in Visual Studio, my app still ran fine and the version references in C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v15.0\TypeScript\Microsoft.TypeScript.targets has been upgraded to 2.1.

Connect with me:RSSGitHubTwitterLinkedIn