Starting out with the ASP.NET Core React template (part 3 - Separating out the frontend)

September 18, 2019 · 4 minute read · Tags: core | react

So now we know our way round the front end part of a new React + Web API project, and the Web API part.

But we left the last post on a bit of a cliffhanger.

We saw how you can choose to launch the React part of the application separately (running on its own port and not tied in with rebuilds of your C# API).

But, if you try this, launch the application and try to access the “Weather” page, you’ll just see the Loading… indicator and no actual data.

Broken URLs

So what’s going on?

Well, now the React frontend is running on localhost:3000, it’s phsyically separated from your ASP.NET Core Web API.

So, the code in FetchData.js is broken…

fetch('api/SampleData/WeatherForecasts')
    .then(response => response.json())
    .then(data => {
    this.setState({ forecasts: data, loading: false });
    });

Fetch is going to assume:

api/SampleData/WeatherForecasts

is located at:

http://localhost:3000/api/SampleData/WeatherForecasts

which is, of course, wrong.

What we actually want to do is hit our API server running on another port (40512 in my case; check Properties/launchSettings.json to discover yours).

Looking to get up and running with React?

All you need is a little nudge in the right direction.

Pop your email in the box below and I'll ping over a link to the subscribers only vault which includes my React + ASP.NET quickstart course; discover how to build any React component and hook it up to an ASP.NET Core backend.

I respect your email privacy. Unsubscribe with one click.

    To fix this we could just manually include the correct address in the fetch call…

    fetch('http://localhost:40512/api/SampleData/WeatherForecasts')
        .then(response => response.json())
        .then(data => {
        this.setState({ forecasts: data, loading: false });
        });
    

    But we could be making a lot of these network calls and it’s not ideal to have to include that first part of the URL in every case (not least because we might change it at some point during development, and definitely when we go live).

    A better way is to define that URL once and use it everywhere; something we can do quite easily using that .env file we added last time.

    Currently it looks like this…

    BROWSER=none
    

    But we can add anything we like to it.

    Let’s add our API URL…

    BROWSER=none
    REACT_APP_API_URL=http://localhost:40512
    

    To be able to retrieve this value in our React (javascript) code it needs to be prefixed with REACT_APP. Now we can retrieve this code whenever we need it like so…

    process.env.REACT_APP_API_URL
    

    So, a little string interpolation later and we end up with this…

    fetch(`${process.env.REACT_APP_API_URL}/api/SampleData/WeatherForecasts`)
        .then(response => response.json())
        .then(data => {
        this.setState({ forecasts: data, loading: false });
        });
    

    Notice the “not quite apostrophe” in there, the backtick at the beginning and end of the url string?

    That allows us to use javascript’s template literals to interpolate expressions in your strings.

    So in this case we’ll get the value of REACT_APP_API_URL pre-pended to the rest of our string.

    Changing the URL in production

    So far so good but we probably don’t want to use localhost in production. To use different settings in different environments we can define more than one .env file.

    So in this case, if we define an .env.development file and put our localhost URL in there, we can put the actual, production, API address in .env.

    That way we should end up with the correct API urls for both development and prod.

    .env

    REACT_APP_API_URL=https://API.YourDomainHere.io
    

    .env.development

    REACT_APP_API_URL=http://localhost:40512
    

    Watch out for CORS

    The final thing you’ll probably run into when you run your app in production is CORS.

    As soon as you have your frontend and API applications running on different URLs, CORS is likely to raise its head and demand your attention!

    If you see an error indicating that a Cross-Origin request was blocked, chances are you’ve run into CORS.

    CORS exists to stop random code running in the browser from making requests to your API, but it has a nasty habit of cropping up when you try and access your API from your own applications as well.

    Happily, you can easily configure ASP.NET Core with a CORS policy which allows your application through to your API,

    Check out this article for more details on CORS and my handy CORS code generator to get the code you need to fix the problem.

    Next up

    Edit and Replay your network requests, direct from the browser
    Half the battle with building a client-side web app (using Blazor, React etc) is figuring out what calls are being made to the network. Now you can see but also edit those requests and replay them…
    Quickly transform any mockup or design into a working Blazor prototype
    Even complicated applications can be broken down into small components, making them much less daunting to build.
    But, which flavor of ASP.NET?
    Blazor, Razor, MVC… what does it all mean?!