Tag Archives: Routing

Capturing Url Parameters in ReactJS using Typescript

This sounds like it’s a very easy thing to do. There are a lot of resources out there on the web, however, I certainly did not find it straight-forward.

My use case here was very simple: the site had failed to do something, I had the reason, and I just wanted to display that to the user (maybe at some stage I’ll move the response into the body, but I thought this would be an easy option for now.

How

The first step is to bring RouteComponentProps into your React file:

import { RouteComponentProps } from 'react-router';

Your component should have a class signature similar to this:

export class AddSiteFailure extends Component<IProps, IState> {

If you’re interested in some common Typescript syntax differences for React, I recently posted on this very subject.

In the above class definition, we’re accepting IProps and IState. IProps needs to be amended slightly:

interface IProps extends RouteComponentProps<IMatchParams> {    
}

interface IState {
}

So, we’re inheriting from the RouteComponentProps that we imported earlier, and we’re telling it that the structure of the parameters will be defined in an interface called IMatchParams. We’ll need to define that:

interface IMatchParams {
    reason: string
}

Okay, so far, we have a standard props structure, but we’re now inheriting from this new RouteComponentProps, and we’re telling it that the URL parameters will be defined in the interface IMatchParams. So, why does IMatchParams have a string property called “reason”?

The answer to that lies in your App.js / App.tsx. This is the file that manages the routing of your app. In the Render method, your file should have an entry similar to this:

<Route path='/addSiteFailure' component={AddSiteFailure} />

So, you need to tell it that you’ll be accepting a parameter, and you need to give that parameter a name; for example:

<Route path='/addSiteFailure/:reason' component={AddSiteFailure} />

Now, when you navigate to the page, the additional Url parameter will be internally referred to as “reason”, which is how it maps to IMatchParams.reason.

Web API Routing – The Basics

Working with API projects, it’s easy to miss some key rules about the routing. This post is basically the result of some that I missed, and subsequent the investigation. It covers some very basic routing rules, and it certainly not intended to be an exhaustive guide.

.Net Framework

Starting with a .Net Framework Web API, let’s create a new web app:

And add a new controller:

Here’s the code for the controller; as you will see, it’s massively complex, but the good news is that you only need to pay attention to the name of the action, and the code inside it:

public class TestController : ApiController
{
    [HttpGet]
    public IHttpActionResult TestAction()
    {
        return Ok("TestAction Performed");
    }
}

Let’s run the project and navigate to the URL:

How did I know that was the URL? It’s magic, and you can buy some of that magic by sending a cheque for the low, low price of $25 to the address shown at the bottom of the screen.

Actually, it’s defined in WebApiConfig.cs:

Parameters

Where there is more than a single function, one surprising (to me) feature is that the parameters that it accepts is more important to the routing than the name of the controller. Here’s a second action with a parameter:

[HttpGet]
public IHttpActionResult TestAction2(string test)
{
    return Ok("TestAction2 Performed");
}

… and here’s it working:

However, should I not give it the parameter that it craves, it hides away, and instead, we get the first function that’s no too fussy about parameters:

It doesn’t even matter whether I just put some drivel as the controller name; the first criteria is the parameter:

This is because, according to this it follows these criteria:

The default implementation is provided by the ApiControllerActionSelector class. To select an action, it looks at the following:
• The HTTP method of the request.
• The “{action}” placeholder in the route template, if present.
• The parameters of the actions on the controller.

So, if we add the {action} placeholder, that ensures that it uses the correct method:

public static void Register(HttpConfiguration config)
{
    // Web API configuration and services
 
    // Web API routes
    config.MapHttpAttributeRoutes();
 
    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        //routeTemplate: "api/{controller}/{id}",
        routeTemplate: "api/{controller}/{action}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
}

Otherwise, we get a best guess based on the parameters.

.Net Core Web API

The rules have changed since switching to .Net Core; WebApiConfig has gone and, in its place, it a localised routing system.

Here, you tell the class how to handle routing; for example, the following:

[Route("api/[controller]")]

Will result anything decorated with HttpGet being called when the controller is called. The parameters must be explicitly decorated; so passing no parameters would look like this:

[HttpGet]
public string OneTest()
{
    return "TestOne";
}

Whereas, a single parameter would look like this:

[HttpGet("{id}")]
public string aaa(int id)
{
    return "value aaa";
}

If you duplicate the signatures then they are not found. As with the framework version, you can simply tell it to look to the action name that you give it:

[Route("api/[controller]/[action]")]
public class TestController : Controller
{
    [HttpGet]
    public IEnumerable<string> TestActionOne()
    {
        return new string[] { "one value1", "value2" };
    }
 
    [HttpGet]
    public string TestActionTwo()
    {
        return "two value";
    }

But, again, it pays no attention to parameters until you decorate it correctly.

References

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing