<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Martin Soderlund Ek</title>
    <description>The latest articles on Forem by Martin Soderlund Ek (@dileno).</description>
    <link>https://forem.com/dileno</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F231478%2F0c5a5e3b-dd8b-4a43-bd63-d6969a38105f.jpg</url>
      <title>Forem: Martin Soderlund Ek</title>
      <link>https://forem.com/dileno</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dileno"/>
    <language>en</language>
    <item>
      <title>Running Entity Framework Core Migrations with Optimizely CMS 12</title>
      <dc:creator>Martin Soderlund Ek</dc:creator>
      <pubDate>Wed, 09 Oct 2024 13:19:56 +0000</pubDate>
      <link>https://forem.com/dileno/running-entity-framework-core-migrations-with-optimizely-57le</link>
      <guid>https://forem.com/dileno/running-entity-framework-core-migrations-with-optimizely-57le</guid>
      <description>&lt;p&gt;So you've added your new Entity Framework &lt;code&gt;DbContext&lt;/code&gt; to the Startup &lt;code&gt;ConfigureServices&lt;/code&gt; method, everything works fine locally when you start your web application. Your database table(s) are created, migrations work both ways. Now you only need this working for other environments.&lt;/p&gt;

&lt;p&gt;Enter the good old initialization engine in Optimizely.&lt;/p&gt;

&lt;p&gt;What we want to do is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Scan all classes inheriting from DbContext.&lt;/li&gt;
&lt;li&gt;Go through your Entity Framework contexts and check if they have pending migrations.&lt;/li&gt;
&lt;li&gt;Apply any pending migrations.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's the full solution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.ServiceLocation;
using Microsoft.EntityFrameworkCore;

[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class EntityFrameworkMigrationInitialization : IConfigurableModule
{
    public void ConfigureContainer(ServiceConfigurationContext context)
    {
        context.Services.AddTransient&amp;lt;EFCoreMigrationService&amp;gt;();
    }

    public void Initialize(InitializationEngine context)
    {
        var migrationService = context.Locate.Advanced.GetInstance&amp;lt;EFCoreMigrationService&amp;gt;();
        migrationService.CheckAndApplyMigrations();
    }

    public void Uninitialize(InitializationEngine context)
    {
    }
}

public class EFCoreMigrationService
{
    private readonly ILogger&amp;lt;EntityFrameworkMigrationInitialization&amp;gt; _logger;
    private readonly IServiceProvider _serviceProvider;

    public EFCoreMigrationService(IServiceProvider serviceProvider, ILogger&amp;lt;EntityFrameworkMigrationInitialization&amp;gt; logger)
    {
        _serviceProvider = serviceProvider;
        _logger = logger;
    }

    public void CheckAndApplyMigrations()
    {
        using (var scope = _serviceProvider.CreateScope())
        {
            // Get all DbContext types in the application
            var dbContextTypes = AppDomain.CurrentDomain.GetAssemblies()
                .Where(a =&amp;gt; !a.IsDynamic &amp;amp;&amp;amp; !a.ReflectionOnly)
                .SelectMany(a =&amp;gt; a.GetTypes())
                .Where(t =&amp;gt; t.IsClass &amp;amp;&amp;amp; !t.IsAbstract &amp;amp;&amp;amp; t.IsSubclassOf(typeof(DbContext)));

            foreach (var contextType in dbContextTypes)
            {
                var context = scope.ServiceProvider.GetService(contextType) as DbContext;
                if (context != null)
                {
                    if (context.Database.GetPendingMigrations().Any())
                    {
                        _logger.LogError($"Applying EF migrations for {contextType.Name}");
                        context.Database.Migrate();
                    }
                }
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>optimizely</category>
      <category>episerver</category>
      <category>entityframework</category>
      <category>efcore</category>
    </item>
    <item>
      <title>Partial Routing in Optimizely 12</title>
      <dc:creator>Martin Soderlund Ek</dc:creator>
      <pubDate>Thu, 01 Feb 2024 11:19:20 +0000</pubDate>
      <link>https://forem.com/dileno/partial-routing-in-optimizely-12-dbb</link>
      <guid>https://forem.com/dileno/partial-routing-in-optimizely-12-dbb</guid>
      <description>&lt;p&gt;If you need to implement partial routing in Optimizely CMS 12, this is a good start.&lt;/p&gt;

&lt;p&gt;There are of course some &lt;a href="https://docs.developers.optimizely.com/content-management-system/docs/partial-routing"&gt;breaking changes as per the documentation&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The interface IPartialRouter changed slightly, and implementations should now be registered in DI container as IPartialRouter, rather than the previous way to register a partial router, which was through the extension method RegisterPartialRoute on RouteCollection&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;OK, lets start with adding a partial router class which implements IPartialRouter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class MyPagePartialRouter : IPartialRouter&amp;lt;MyPage, MyPage&amp;gt;
    {
        public MyPagePartialRouter() { }

        public object RoutePartial(MyPage content, UrlResolverContext urlResolverContext)
        {
            urlResolverContext.RouteValues.Add("requestPath", urlResolverContext.RemainingSegments);
            urlResolverContext.RemainingSegments = Array.Empty&amp;lt;Char&amp;gt;();
            return content;
        }

        public PartialRouteData GetPartialVirtualPath(MyPage content, UrlGeneratorContext urlGeneratorContext)
        {
            return null;
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We add our params to the &lt;code&gt;RouteValues&lt;/code&gt; collection. Note we use &lt;code&gt;RemainingSegments&lt;/code&gt; instead of RemainingPath.&lt;/p&gt;

&lt;p&gt;Then we need to register it in a DI container like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;services.AddSingleton&amp;lt;IPartialRouter, MyPagePartialRouter&amp;gt;();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And that's it!&lt;/p&gt;

</description>
      <category>optimizely</category>
      <category>netcore</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Customize the Optimizely CMS Login Page</title>
      <dc:creator>Martin Soderlund Ek</dc:creator>
      <pubDate>Mon, 16 Oct 2023 09:46:13 +0000</pubDate>
      <link>https://forem.com/dileno/customize-the-optimizely-cms-login-page-3blp</link>
      <guid>https://forem.com/dileno/customize-the-optimizely-cms-login-page-3blp</guid>
      <description>&lt;p&gt;The Optimizely CMS Login Page can be customized to fit your brand. Here's how.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Quha7NAf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jers1kxjbp97jeyo98n6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Quha7NAf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jers1kxjbp97jeyo98n6.png" alt="Image description" width="800" height="408"&gt;&lt;/a&gt;The default one which we can modify..&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;.NET Core&lt;/strong&gt; based websites (Optimizely CMS 12 and later) this can be configured in the Startup.cs file and &lt;code&gt;Configure&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;The simplest thing is to add a &lt;strong&gt;request delegate&lt;/strong&gt; to the &lt;code&gt;Configure&lt;/code&gt; method, looking for the default CSS file and background image, and replace them, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.Use(requestDelegate =&amp;gt;
{
    return new RequestDelegate(context =&amp;gt;
    {
        if (Regex.Match(context.Request.Path, "^\\/Util\\/styles\\/login\\.css", RegexOptions.IgnoreCase).Success)
        {
            context.Request.Path = new PathString("/ClientResources/Styles/EpiserverLogin.css");
        }

        if (Regex.Match(context.Request.Path, "^\\/Util\\/images\\/login\\/login-background-image\\.png", RegexOptions.IgnoreCase).Success)
        {
            context.Request.Path = new PathString("/ClientResources/Images/LoginImage.webp");
        }

        return requestDelegate(context);
    });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can make this a separate middle ware class but I think this is pretty self-explanatory and clean. Note the paths.&lt;/p&gt;

&lt;p&gt;For .NET framework based websites (Optimizely 11 and earlier), the same can be done with an &lt;code&gt;InitializableModule&lt;/code&gt; and &lt;code&gt;HttpContext.Current.RewritePath&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>optimizely</category>
      <category>episerver</category>
      <category>dotnetcore</category>
    </item>
    <item>
      <title>IOS Render Component Bug in Vue 3</title>
      <dc:creator>Martin Soderlund Ek</dc:creator>
      <pubDate>Wed, 30 Nov 2022 09:54:18 +0000</pubDate>
      <link>https://forem.com/dileno/ios-render-component-bug-in-vue-3-3p24</link>
      <guid>https://forem.com/dileno/ios-render-component-bug-in-vue-3-3p24</guid>
      <description>&lt;p&gt;Recently we had a problem where we toggled a CSS class &lt;code&gt;disabled&lt;/code&gt; on a component like this:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;my-button :class="{ disabled: !readyToSubmit }" @click="handleSubmit"&amp;gt;Submit&amp;lt;/my-button&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;The CSS class &lt;em&gt;disabled&lt;/em&gt; is toggled depending on the computed property &lt;em&gt;readyToSubmit&lt;/em&gt;'s boolean value.&lt;/p&gt;

&lt;p&gt;The problem was, only a few parts of the button changed on IOS/Safari, where all parts of the button changed on all other devices and browsers.&lt;/p&gt;

&lt;p&gt;In short, this means the component wasn't properly re-rendered.&lt;/p&gt;

&lt;p&gt;How can we best trigger a re-render in Vue? &lt;strong&gt;By adding the built in key special attribute to the component and changing its value&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Simply like this:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;my-button :class="{ disabled: !readyToSubmit }" @click="handleSubmit" :key="`MyBtn-${!readyToSubmit}`"&amp;gt;Submit&amp;lt;/my-button&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;To better help Vue to keep track of what has changed and what hasn't, we supply a key attribute.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vuejs.org/api/built-in-special-attributes.html#key"&gt;More on the key attribute in the Vue documentation&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>vue3</category>
    </item>
    <item>
      <title>Setting up External File Storage in Optimizely CMS 12 (preview)</title>
      <dc:creator>Martin Soderlund Ek</dc:creator>
      <pubDate>Fri, 10 Sep 2021 13:26:38 +0000</pubDate>
      <link>https://forem.com/dileno/setting-up-external-file-storage-in-optimizely-cms-12-preview-2p8o</link>
      <guid>https://forem.com/dileno/setting-up-external-file-storage-in-optimizely-cms-12-preview-2p8o</guid>
      <description>&lt;p&gt;Optimizely (formerly Episerver) CMS 12 comes with lots of exciting new stuff, including .NET 5 support (thank you finally!).&lt;/p&gt;

&lt;p&gt;Setting up a new website in a development environment is easy (&lt;a href="https://github.com/episerver/netcore-preview"&gt;Clone the .NET 5 preview repo here&lt;/a&gt;), however when you want a shared file share for the blobs (instead of the local App_Data folder), it's a little bit hard to find the accurate documentation for it.&lt;/p&gt;

&lt;p&gt;To configure an Optimizely CSM 12 (preview) website to use a file share, you need to edit the &lt;code&gt;appSettings.json&lt;/code&gt; file to include &lt;code&gt;BlogProviderOptions&lt;/code&gt;, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "EPiServer":{
     "Cms":{
            "BlobProvidersOptions": {
                "DefaultProvider": "fileShare",
                "Providers": {
                    "fileShare": "EPiServer.Framework.Blobs.FileBlobProvider, EPiServer.Framework"
                },
             } 
             "FileBlobProvider":{
                 "Path": "\\dbserver\blobs"
             }
     }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Until you do so, the &lt;code&gt;App_Data&lt;/code&gt; folder will be used for your CMS content files.&lt;/p&gt;

&lt;p&gt;The documentation for this can be found under the &lt;a href="https://world.optimizely.com/documentation/developer-guides/optimizely-platform/-net-core-preview/CMS/Deployment/deployment-scenarios/Deploying-to-Windows-servers/"&gt;Deploying to Windows Servers&lt;/a&gt; section.&lt;/p&gt;

</description>
      <category>optimizely</category>
      <category>episerver</category>
      <category>blobs</category>
      <category>cms</category>
    </item>
    <item>
      <title>Set Nuget Proxy</title>
      <dc:creator>Martin Soderlund Ek</dc:creator>
      <pubDate>Thu, 09 Sep 2021 06:48:13 +0000</pubDate>
      <link>https://forem.com/dileno/set-nuget-proxy-3d1n</link>
      <guid>https://forem.com/dileno/set-nuget-proxy-3d1n</guid>
      <description>&lt;p&gt;When performing a &lt;code&gt;dotnet tool install&lt;/code&gt; or similar command, you get an error like this one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Unable to load the service index for source https://api.nuget.org/v3/index.json.
The SSL connection could not be established, see inner exception.
Received an unexpected EOF or 0 bytes from the transport stream.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might then need to set proxy for Nuget.&lt;br&gt;
Open &lt;code&gt;Nuget.config&lt;/code&gt; in C:\users\YOUR_USER\AppData\Roaming\Nuget\Nuget.config&lt;/p&gt;

&lt;p&gt;Add this &lt;code&gt;config&lt;/code&gt; section to the &lt;code&gt;configuration&lt;/code&gt; element:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;config&amp;gt;
  &amp;lt;add key="http_proxy" value="http://your-proxy-url:8080" /&amp;gt;
  &amp;lt;add key="https_proxy" value="https://your-proxy-url:8080" /&amp;gt;
&amp;lt;/config&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your Nuget.config might then look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;configuration&amp;gt;
  &amp;lt;packageSources&amp;gt;
    ...
  &amp;lt;/packageSources&amp;gt;
  &amp;lt;config&amp;gt;
    &amp;lt;add key="http_proxy" value="http://your-proxy-url:8080" /&amp;gt;
    &amp;lt;add key="https_proxy" value="https://your-proxy-url:8080" /&amp;gt;
  &amp;lt;/config&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>nuget</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Set Git Proxy</title>
      <dc:creator>Martin Soderlund Ek</dc:creator>
      <pubDate>Thu, 09 Sep 2021 06:34:33 +0000</pubDate>
      <link>https://forem.com/dileno/set-git-proxy-3i69</link>
      <guid>https://forem.com/dileno/set-git-proxy-3i69</guid>
      <description>&lt;p&gt;You clone a Git repo and get this error message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Git failed with a fatal error.
unable to access 'https://github.com/THE_REPO':
OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection github.com:443
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This might be because you're behind a proxy. You then need to set proxy for Git in your command tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global http.proxy http://your-proxy-url:8080
git config --global https.proxy https://your-proxy-url:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You also might need to disable SSL verification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global http.sslVerify false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>github</category>
    </item>
    <item>
      <title>Set npm Proxy</title>
      <dc:creator>Martin Soderlund Ek</dc:creator>
      <pubDate>Thu, 09 Sep 2021 06:26:54 +0000</pubDate>
      <link>https://forem.com/dileno/set-npm-proxy-1e0d</link>
      <guid>https://forem.com/dileno/set-npm-proxy-1e0d</guid>
      <description>&lt;p&gt;When you do an &lt;code&gt;npm install&lt;/code&gt; and get an error message like this one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm ERR! code ECONNRESET
npm ERR! errno ECONNRESET
npm ERR! network request to https://registry.npmjs.org/windows-build-tools failed, reason: Client network socket disconnected before secure TLS connection was established
npm ERR! network This is a problem related to network connectivity.
npm ERR! network In most cases you are behind a proxy or have bad network settings.
npm ERR! network
npm ERR! network If you are behind a proxy, please make sure that the
npm ERR! network 'proxy' config is set properly.  See: 'npm help config'

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the problem might be you're behind a proxy and need to configure this for npm.&lt;/p&gt;

&lt;p&gt;You need to set &lt;code&gt;proxy&lt;/code&gt; and &lt;code&gt;https-proxy&lt;/code&gt; for npm, like this (in your preferred command tool):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm config set proxy http://your-proxy-url:8080
npm config set https-proxy https://your-proxy-url:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Setting &lt;code&gt;strict-ssl&lt;/code&gt; to false might be an idea too, if you really know what you're doing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm config set strict-ssl false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>npm</category>
    </item>
    <item>
      <title>React Hooks and API Call Sample App</title>
      <dc:creator>Martin Soderlund Ek</dc:creator>
      <pubDate>Sat, 19 Oct 2019 18:19:56 +0000</pubDate>
      <link>https://forem.com/dileno/react-hooks-and-api-call-sample-app-16gg</link>
      <guid>https://forem.com/dileno/react-hooks-and-api-call-sample-app-16gg</guid>
      <description>&lt;p&gt;Last time around I wrote about a &lt;a href="https://dev.to/dileno/react-sample-app-with-api-call-and-update-to-latest-version-30cl"&gt;React sample app with an API call to RandomUser.me&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That version was classic React and now I've updated it to use hooks instead.&lt;/p&gt;

&lt;p&gt;With classic React, we used Class components and mutated their internal state via &lt;code&gt;setState&lt;/code&gt; when we wanted to do something.&lt;/p&gt;

&lt;p&gt;With React hooks, we can use functional components instead, with the State hook &lt;code&gt;useState&lt;/code&gt;, which itself is a React function.&lt;/p&gt;

&lt;p&gt;We will import &lt;code&gt;useState&lt;/code&gt; like this at the top of our file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import React, { useState } from "react";&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then we'll declare our functional component, like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;export default function RandomUser() {}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then we will use EcmaScript 6 (ES6) destructuring and &lt;code&gt;useState&lt;/code&gt; to return an array for use in our component:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const [name, setName] = useState([]);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;user&lt;/code&gt; and &lt;code&gt;setUser&lt;/code&gt; variable names can be anything you want, as long as they are descriptive, of course.&lt;/p&gt;

&lt;p&gt;Then we'll use the Effect hook &lt;code&gt;useEffect&lt;/code&gt; to initialize our function and insert it into the tree. &lt;code&gt;useEffect&lt;/code&gt; "serves the same purpose as &lt;code&gt;componentDidMount&lt;/code&gt;, &lt;code&gt;componentDidUpdate&lt;/code&gt;, and &lt;code&gt;componentWillUnmount&lt;/code&gt; in React classes, but unified into a single API". (&lt;a href="https://reactjs.org/docs/hooks-overview.html"&gt;React Hooks documentation&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Sweet - &lt;code&gt;useEffect&lt;/code&gt; takes care of a lot for us!&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;As you can see, we have a call to &lt;code&gt;fetchRandomUser()&lt;/code&gt;, which will be an async function with our API call.&lt;/p&gt;

&lt;p&gt;The complete code looks like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Compare this functional component with hooks sample, to the &lt;a href="https://dev.to/dileno/react-sample-app-with-api-call-and-update-to-latest-version-30cl"&gt;previous class components sample&lt;/a&gt;, we now have 48 rows, vs 65 rows before.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/dileno/hello-react/tree/hello-react-hooks"&gt;Here's the Github repo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
    </item>
    <item>
      <title>React Sample App with API Call and Update to Latest Version</title>
      <dc:creator>Martin Soderlund Ek</dc:creator>
      <pubDate>Fri, 20 Sep 2019 10:12:50 +0000</pubDate>
      <link>https://forem.com/dileno/react-sample-app-with-api-call-and-update-to-latest-version-30cl</link>
      <guid>https://forem.com/dileno/react-sample-app-with-api-call-and-update-to-latest-version-30cl</guid>
      <description>&lt;p&gt;A while back I created a small and simple React app in order to fetch a random user from the &lt;a href="https://randomuser.me/"&gt;RandomUser.me API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can &lt;a href="https://github.com/dileno/hello-react"&gt;find the React app on my GitHub: hello-react&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have a RandomUser component which simply looks like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We fetch a user from the API and present the user's name and picture, if present.&lt;/p&gt;

&lt;p&gt;In our &lt;strong&gt;App.js&lt;/strong&gt; file we then return the &lt;code&gt;RandomUser&lt;/code&gt; component together with some HTML:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In the VS Code terminal we run the &lt;code&gt;npm start&lt;/code&gt; command and our React app is compiled and we can look at it in the browser on &lt;a href="http://localhost:3000/"&gt;http://localhost:3000/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After commit to Github, I got a few security messages back, as expected.&lt;/p&gt;

&lt;p&gt;First, I checked React version with this command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm list react&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and got &lt;code&gt;-- react@16.8.6&lt;/code&gt; back, which isn't the latest version. To install latest React version, I had to run this command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install --save react@latest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And then update packages in the React app with this command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm audit fix&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I also manually had to update &lt;code&gt;lodash.template&lt;/code&gt; to 4.5.0:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install --save lodash.template@latest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can &lt;a href="https://github.com/dileno/hello-react"&gt;find the React app on my GitHub: hello-react @ dileno&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>vscode</category>
      <category>npm</category>
    </item>
    <item>
      <title>Build an Angular 8 App with REST API and ASP.NET Core 2.2 - part 2</title>
      <dc:creator>Martin Soderlund Ek</dc:creator>
      <pubDate>Wed, 18 Sep 2019 08:31:44 +0000</pubDate>
      <link>https://forem.com/dileno/build-an-angular-8-app-with-rest-api-and-asp-net-core-2-2-part-2-46ap</link>
      <guid>https://forem.com/dileno/build-an-angular-8-app-with-rest-api-and-asp-net-core-2-2-part-2-46ap</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/dileno/build-a-simple-crud-app-with-angular-8-and-asp-net-core-2-2-part-1-back-end-39e1"&gt;In part 1 of this tutorial, we built the ASP.NET Core back-end&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 2 - Create the Angular 8 app
&lt;/h2&gt;

&lt;p&gt;Now, let’s finally start with the Angular app. We will use &lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; and &lt;a href="https://cli.angular.io/" rel="noopener noreferrer"&gt;Angular CLI&lt;/a&gt; to generate the Angular project and necessary files.&lt;/p&gt;

&lt;p&gt;Remember. &lt;strong&gt;&lt;a href="https://github.com/dileno/Blog-tutorial-Angular-8-.NET-Core-2.2-CRUD" rel="noopener noreferrer"&gt;Github repo is here: Angular 8 blog app tutorial using .NET Core 2.2 and Entity Framework back-end&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://cli.angular.io/" rel="noopener noreferrer"&gt;Angular CLI&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;VS Code&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When Node.js is installed, you can open the Node.js command prompt.&lt;/p&gt;

&lt;p&gt;Execute this command in the command prompt to install the Angular 8 CLI:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install -g @angular/cli&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will install the latest Angular CLI globally and it’ll take a little while. When you’re done, you can check the Angular version with this command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ng --version&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The Node.js command prompt should look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F8grcou3t6vx9dqztvtyu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F8grcou3t6vx9dqztvtyu.png" alt="Node.js command prompt and Angular CLI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let's move to the folder where our Visual Studio back-end is located. Use the cd command to do this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd c:/projects/blog&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We will simply call our Angular 8 application &lt;strong&gt;ClientApp&lt;/strong&gt;. Let’s execute the command that creates our Angular application:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ng new ClientApp&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We’ll be prompted with some questions. We want to use routing (press Y) and stylesheet format: SCSS. Then let Node do its thing and create the web app. It’ll take a minute or so.&lt;/p&gt;

&lt;p&gt;When the app is created, cd command into the app folder:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd ClientApp&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And then build and run the app with the &lt;code&gt;ng serve&lt;/code&gt; command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ng serve&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The command prompt will look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnrfqojfoq22xiyhv77i7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnrfqojfoq22xiyhv77i7.png" alt="Node.js Angular app compilation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The build succeded and now you can browse to your Angular app with the URL &lt;strong&gt;&lt;a href="http://localhost:4200" rel="noopener noreferrer"&gt;http://localhost:4200&lt;/a&gt;&lt;/strong&gt;. The basic Angular 8 app is based on a template and it’ll look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F9yfk0r3dofkc9axtaqzd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F9yfk0r3dofkc9axtaqzd.png" alt="Angular template app in the browser"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have a look at the source code, it’ll look like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The interesting thing here is &lt;code&gt;&amp;lt;app-root&amp;gt;&amp;lt;/app-root&amp;gt;&lt;/code&gt;, which is Angular specific and tells us where our Angular app will execute.&lt;/p&gt;

&lt;p&gt;One final command is good to know — it’s &lt;code&gt;Ctrl+C&lt;/code&gt; to close the Angular application, and you should &lt;strong&gt;press it twice&lt;/strong&gt; to terminate the batch job and stop ng serve.&lt;/p&gt;

&lt;p&gt;One of the nice features of Angular development is &lt;strong&gt;changes you save in front-end files will immediately be reflected in the browser&lt;/strong&gt;. For this to happen the app needs to be running.&lt;/p&gt;

&lt;p&gt;For some changes though, like adding Bootstrap, you need to restart the application to make it work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Angular 8 fundamentals
&lt;/h2&gt;

&lt;p&gt;Let’s pause, take a step back and learn some of the Angular 8 fundamentals.&lt;/p&gt;

&lt;p&gt;Angular 8 is an open source client-side JavaScript framework, based on TypeScript which is compiled to JavaScript.&lt;/p&gt;

&lt;p&gt;The Angular 8 architecture consists of the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Modules&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Components&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Templates, Directives, Data-Binding&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Services and dependency injection&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Routing&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can delve deeper into the &lt;a href="https://angular.io/guide/architecture" rel="noopener noreferrer"&gt;Angular architecture here in the official documentation&lt;/a&gt;. Here’s a quick rundown though:&lt;/p&gt;

&lt;h3&gt;
  
  
  Modules
&lt;/h3&gt;

&lt;p&gt;Angular NgModules are fundamental to any Angular application. Every Angular app has a root module called AppModule, which bootstraps and launches the app. Modules can call components and services. The default module is &lt;strong&gt;app.module.ts&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Components
&lt;/h3&gt;

&lt;p&gt;Components provide us with a class and a view, and are parts of the application. The class is TypeScript based and the view is HTML. All Angular app has at least one component called &lt;strong&gt;app.component.ts&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Templates, directives, data-binding
&lt;/h3&gt;

&lt;p&gt;A template combines HTML with Angular markup. The directives provide logic and the binding markup connects the application data with the DOM.&lt;/p&gt;

&lt;h3&gt;
  
  
  Services and dependency injection
&lt;/h3&gt;

&lt;p&gt;Service classes provide application logic that isn’t tied to a specific view and shared across the app. They are injectable using the @Injectable() decorator. Component classes are kept nice and tidy using dependency injection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Routing
&lt;/h3&gt;

&lt;p&gt;The Router NgModule provides a service that defines navigation in the app. It works the same way as a browser’s navigation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Visual Studio 2019 for back-end, VS Code for front-end
&lt;/h2&gt;

&lt;p&gt;While Visual Studio 2019 works very well for back-end as well as front-end, &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;VS Code&lt;/a&gt; is actually better for front-end heavy work with frameworks like Angular. I recommend you try VS Code and most instructions for the Angular application in this tutorial, will be for VS Code.&lt;/p&gt;

&lt;p&gt;To make front-end and Angular development easier in VS Code, install these extensions. You can do it easiest through the VS Code Extensions module.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=johnpapa.Angular2" rel="noopener noreferrer"&gt;Angular Snippets (Version 8)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome" rel="noopener noreferrer"&gt;Debugger for Chrome&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-typescript-tslint-plugin" rel="noopener noreferrer"&gt;TSLint&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There’s obviously a lot more awesome extensions like Beautify and Path Intellisense that makes your development more productive. It’s all up to your preference and style.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In VS Code, make sure you open the folder ClientApp on your disk and work from there.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Add components and services to our Angular app
&lt;/h2&gt;

&lt;p&gt;Let’s continue building the Angular app. First, press Ctrl+C twice in the Node.js command prompt, if you haven’t closed the connection to your app.&lt;/p&gt;

&lt;p&gt;Next, let’s add Bootstrap 4 to the application. Execute this command in the Node.js command prompt:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install bootstrap --save&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then find the &lt;strong&gt;angular.json&lt;/strong&gt; file and edit the build node to make styles look like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The angular.json build node should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnw5zlgxdwx1czuzbj83h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnw5zlgxdwx1czuzbj83h.png" alt="Angular.json build node"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next up, let’s create our &lt;strong&gt;components&lt;/strong&gt;. We will have three components for our blog application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;BlogPosts — shows all blog posts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;BlogPost — show a specific blog post.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;BlogPostAddEdit — add new or edit existing blog post.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To create these components, execute the following commands in the Node.js command prompt:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

ng generate component BlogPosts
ng generate component BlogPost
ng generate component BlogPost-AddEdit


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Under ClientApp/src/app, the components are now there:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Focuyk0hh3w275xv7gp54.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Focuyk0hh3w275xv7gp54.png" alt="Components (blog-posts folder) in VS Code"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, we have a .html file, scss file, spec.ts file and component.ts file for each component.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;HTML and SCSS are used for the view.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;spec.ts is for tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;component.ts contains our component class and logic.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While we’re at it, let’s create our service as well, using the command prompt:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ng generate service BlogPost&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Create a new folder under app and call it &lt;strong&gt;services&lt;/strong&gt;. Move the two generated service files to the folder:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F4h3bif976tzowcjjftwh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F4h3bif976tzowcjjftwh.png" alt="Services folder in VS Code"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let’s leave our components and services and have a look at the &lt;strong&gt;app.module.ts&lt;/strong&gt; file. This is where we import modules and components, declare them and also add providers.&lt;/p&gt;

&lt;p&gt;We get a few things for free from the created app. Necessary imports are added and a few modules too. When we add components in the Node.js command prompt, the app.modules.ts file is updated as well. However we don’t get help with everything. For our blog app, we need to manually import some modules on our own and add them. We also need to import and add our service to providers.&lt;/p&gt;

&lt;p&gt;Let’s update the file to look like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Necessary modules like &lt;code&gt;HttpClientModule&lt;/code&gt; and &lt;code&gt;ReactiveFormsModule&lt;/code&gt; are imported. &lt;code&gt;AppRoutingModule&lt;/code&gt; and &lt;code&gt;AppComponent&lt;/code&gt; were already created for us from the beginning.&lt;/p&gt;

&lt;p&gt;Just make sure to declare components, add modules to imports and also add our service to providers.&lt;/p&gt;

&lt;p&gt;Just one thing on import and export.&lt;/p&gt;

&lt;p&gt;TypeScript uses the module concept from EcmaScript 2015. Modules are executed in their own scope and not in the global scope. To make one module’s classes, variables, functions etc visible to other modules, export is used. Also to use some of these from another module, an import is needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup routing
&lt;/h2&gt;

&lt;p&gt;Open &lt;strong&gt;app-routing.module.ts&lt;/strong&gt;. Here you have the routes setup with no routes configured:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const routes: Routes = [];&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Update the file to look like this instead:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We import necessary component and update Routes with paths and tell what components will be loaded in those paths.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{ path: '', component: BlogPostsComponent, pathMatch: 'full' }&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This tells us we will load the BlogPostsComponent on the app start page.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{ path: '**', redirectTo: '/' }&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This tells us all invalid paths for the application will be redirected to the start page.&lt;/p&gt;

&lt;p&gt;Open &lt;strong&gt;app.component.html&lt;/strong&gt; and update the file to look like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;&amp;lt;router-outlet&amp;gt;&amp;lt;/router-outlet&amp;gt;&lt;/code&gt; element will be replaced by the correct component and this file will be used for all components in the app.&lt;/p&gt;

&lt;p&gt;Now let’s build and run the app again using the &lt;code&gt;ng serve&lt;/code&gt; command in the Node.js command prompt. When Node is done compiling, go to &lt;a href="http://localhost:4200." rel="noopener noreferrer"&gt;http://localhost:4200&lt;/a&gt;. The start page will now look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnn0n9mns3kjpu585gavj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnn0n9mns3kjpu585gavj.png" alt="Basic Angular app start page - blog posts listing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is our BlogPostsComponent in action. Try browsing to &lt;a href="http://localhost:4200/add" rel="noopener noreferrer"&gt;http://localhost:4200/add&lt;/a&gt; as well and you’ll get the view for our BlogPostAddEditComponent.&lt;/p&gt;

&lt;p&gt;If you try to browse to a path that doesn’t exist, you’re redirected to the start page again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Different ways to build and run the application
&lt;/h2&gt;

&lt;p&gt;We have two different ways that we can use to build and run our Angular application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Node.js command prompt and &lt;code&gt;ng serve&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Visual Studio F5 command and IIS Express.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is good to know. The simplest thing to do is to just use Visual Studio to build and run our Angular app as well as the back-end. To make the Angular app work, we need to edit &lt;strong&gt;Startup.cs&lt;/strong&gt; to allow SPA static files.&lt;/p&gt;

&lt;p&gt;In Startup.cs, we already have commented out configuration for SPA. In the ConfigureServices method, uncomment the &lt;code&gt;services.AddSpaStaticFiles&lt;/code&gt; section:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In the Configure method, uncomment the &lt;code&gt;app.UseSpaStaticFiles()&lt;/code&gt; line and &lt;code&gt;app.UseSpa()&lt;/code&gt; section. Since before, we already have &lt;code&gt;app.UseMvc()&lt;/code&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Also, let’s update &lt;strong&gt;environment.ts&lt;/strong&gt;. Add &lt;code&gt;appUrl&lt;/code&gt; to the environment constant, it should look like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now in Visual Studio 2019, press F5 and your Angular app AND back-end will be up and running on the same address, on IIS Express:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fsdor5ivz8pgspsdyyxvz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fsdor5ivz8pgspsdyyxvz.png" alt="IIS Express browser url"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whether you want to use the Node.js command prompt to build and run the Angular application is up to you. Just remember the back-end needs to be up and running too.&lt;/p&gt;

&lt;p&gt;Visual Studio building and running both the front-end and back-end means one less thing to think about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create blog post model and service methods
&lt;/h2&gt;

&lt;p&gt;We need a blog post model to work with in TypeScript. Let’s create a new folder called models and then a TypeScript file(right click the folder -&amp;gt; New file in VS Code) and name it &lt;strong&gt;blogpost.ts&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Copy and paste this BlogPost model class into blogposts.ts:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Our BlogPost model will now be available across the application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Angular 8 service CRUD tasks
&lt;/h3&gt;

&lt;p&gt;Our Angular service will call our back-end and carry out these tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create blog post.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show all blog posts / show a single blog post.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update an existing blog post.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete a blog post.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now let’s go back to our previously created service, located in the services folder. Open &lt;strong&gt;blog-post.service.ts&lt;/strong&gt; and edit the file to look like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We already injected the service into the providers array in app.module.ts, meaning the service can be used right away across the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Observables in Angular
&lt;/h2&gt;

&lt;p&gt;The Angular HttpClient methods use &lt;strong&gt;RxJS observables&lt;/strong&gt;. Observables provide support for passing messages between publishers and subscribers in your application. They are powerful and have several advantages and are therefore used extensively in Angular.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://angular.io/guide/observables" rel="noopener noreferrer"&gt;Observables in the Angular documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we’ve created (published) an observable, we need to use the subscribe() method to receive notifications. We then get a Subscription object we can work with. Also, we can use unsubscribe() to stop receiving notifications.&lt;/p&gt;

&lt;p&gt;We make our BlogPostService injectable via the &lt;code&gt;@Injectable()&lt;/code&gt; decorator. We will inject the service into our components later.&lt;/p&gt;

&lt;p&gt;For our service’s post and put methods, we will send &lt;code&gt;application/json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then we use the &lt;code&gt;pipe()&lt;/code&gt; method for each service call. Here we can pass in operator functions for data transformation in our observable collection. We add &lt;code&gt;retry&lt;/code&gt; and &lt;code&gt;catchError&lt;/code&gt; to our pipe method.&lt;/p&gt;

&lt;p&gt;It’s very common to subscribe to observables in Angular. This is fine, but you have to remember to unsubscribe too. pipe does that automatically for you, freeing up memory resources and preventing leaks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Update components to show service data
&lt;/h2&gt;

&lt;p&gt;Over to our three blog components. Let’s start with BlogPostsComponent which will list all our blog posts. Update the file &lt;strong&gt;blog-posts.component.ts&lt;/strong&gt; to look like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We dependency inject &lt;code&gt;BlogPostService&lt;/code&gt; in the constructor and in &lt;code&gt;loadBlogPosts()&lt;/code&gt; we simply call our Angular service.&lt;/p&gt;

&lt;p&gt;Since the service &lt;code&gt;getBlogPosts()&lt;/code&gt; method gives us an &lt;code&gt;Observable&amp;lt;BlogPost[]&amp;gt;&lt;/code&gt; back, we assign it to this component’s &lt;code&gt;blogPost$&lt;/code&gt; object. It’s common practice to name observable objects with a $ sign at the end.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;delete()&lt;/code&gt; method we need to subscribe to our observable instead to execute the action and then reload the blog post list.&lt;/p&gt;

&lt;p&gt;Now open &lt;strong&gt;blog-posts.component.html&lt;/strong&gt; and update it to look like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We use the &lt;code&gt;AsyncPipe&lt;/code&gt; to subscribe to our observables. When we want to display our observable value in our HTML template file we use this syntax:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(blogPosts$ | async)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ngIf&lt;/code&gt; and &lt;code&gt;ngFor&lt;/code&gt; are &lt;strong&gt;structural directives&lt;/strong&gt; which change the DOM structure by adding or removing elements.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;routerLink&lt;/code&gt; directive lets us link to specific routes in our app.&lt;/p&gt;

&lt;p&gt;You can press F5 in Visual Studio 2019 or use the Node.js command prompt and &lt;code&gt;ng serve&lt;/code&gt; to launch the app. If you use Node.js to launch the app, make sure the back-end is launched as well in the background (using Visual Studio F5 command).&lt;/p&gt;

&lt;p&gt;Since we’ve manually added a blog post in Postman before, we should now see this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fftbx38hekegra6zbv2my.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fftbx38hekegra6zbv2my.png" alt="Blog posts list view"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Excellent!&lt;/p&gt;

&lt;p&gt;Next up is &lt;strong&gt;blog-post.component.ts&lt;/strong&gt; to view a single blog post. Edit the file to look like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;As it’s a single blog post we want to show, we fetch the id key from the url querystring with the built in &lt;code&gt;ActivatedRoute&lt;/code&gt; component, and pass it to the service &lt;code&gt;getBlogPost()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;Now open &lt;strong&gt;blog-post.component.html&lt;/strong&gt; and edit it to look like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We use the &lt;code&gt;AsyncPipe&lt;/code&gt; again and also use the alias &lt;code&gt;blogPost&lt;/code&gt; so we don’t have to write &lt;code&gt;blogPost | async&lt;/code&gt; everywhere we want to access a blogPost property. We also provide a loading screen.&lt;/p&gt;

&lt;p&gt;We’re getting closer. Now we just need a way to create new blog posts and edit existing ones. Open &lt;strong&gt;blog-post-add-edit.component.ts&lt;/strong&gt; and edit it to look like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Here we’re introducing Angular forms: &lt;code&gt;FormBuilder&lt;/code&gt;, &lt;code&gt;FormGroup&lt;/code&gt; and also &lt;code&gt;Validators&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Depending on if we’re creating a new blog post or editing an existing one, we use &lt;code&gt;actionType&lt;/code&gt; to show the correct form view with or without data. When we save or update a blog post, we create a new &lt;code&gt;BlogPost&lt;/code&gt; object which we then fill with correct form data and then post to our service.&lt;/p&gt;

&lt;p&gt;Let’s open the &lt;strong&gt;blog-post-add-edit.component.html&lt;/strong&gt; and edit it to look like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Here’s the form with validation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We’re done!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Press F5 in Visual Studio 2019 or use the Node.js command prompt and &lt;code&gt;ng serve&lt;/code&gt; to browse our final app. (If you use Node.js to launch the app, make sure the back-end is launched as well in the background (using Visual Studio F5 command))&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F6ld1bti4b55ekw0y1so3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F6ld1bti4b55ekw0y1so3.png" alt="Updated blog posts list view"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fzr6t46pxstu67740dn01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fzr6t46pxstu67740dn01.png" alt="Edit blog post view"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fa05wf4bav48dfilmqwqa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fa05wf4bav48dfilmqwqa.png" alt="Single blog post view"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
      <category>vscode</category>
      <category>node</category>
    </item>
    <item>
      <title>Build a Simple CRUD App with Angular 8 and ASP.NET Core 2.2 - part 1 - back-end</title>
      <dc:creator>Martin Soderlund Ek</dc:creator>
      <pubDate>Wed, 18 Sep 2019 08:31:30 +0000</pubDate>
      <link>https://forem.com/dileno/build-a-simple-crud-app-with-angular-8-and-asp-net-core-2-2-part-1-back-end-39e1</link>
      <guid>https://forem.com/dileno/build-a-simple-crud-app-with-angular-8-and-asp-net-core-2-2-part-1-back-end-39e1</guid>
      <description>&lt;h2&gt;
  
  
  Part 1 - back-end with ASP.NET Core 2.2 and Entity Framework Core
&lt;/h2&gt;

&lt;p&gt;Let’s take a look at how to build a CRUD web app using ASP.NET Core 2.2, Entity Framework Core, and Angular 8. This is part 1 where we focus on the back-end.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/dileno/build-an-angular-8-app-with-rest-api-and-asp-net-core-2-2-part-2-46ap"&gt;Part 2 is here - Angular 8 app with REST API&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;We’ll have a REST API in the back-end and the Angular app on the front-end.&lt;/p&gt;

&lt;p&gt;The basic CRUD app will be a blog, where we can &lt;strong&gt;C&lt;/strong&gt;reate, &lt;strong&gt;R&lt;/strong&gt;ead, &lt;strong&gt;U&lt;/strong&gt;pdate, and &lt;strong&gt;D&lt;/strong&gt;elete blog posts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/dileno/Blog-tutorial-Angular-8-.NET-Core-2.2-CRUD" rel="noopener noreferrer"&gt;Github repo is here: Angular 8 blog app tutorial using .NET Core 2.2 and Entity Framework back-end&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dotnet.microsoft.com/download" rel="noopener noreferrer"&gt;.NET Core 2.2 SDK&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://visualstudio.microsoft.com/vs/" rel="noopener noreferrer"&gt;Visual Studio 2019&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the Angular front-end we'll also use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;VS Code&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://cli.angular.io/" rel="noopener noreferrer"&gt;Angular CLI&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Make sure above are installed. We will use Visual Studio 2019 for the back-end and VS Code for the front-end. You can however use only Visual Studio 2019 if you want to.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;As of Sept 15th, there are previews of .NET Core 3 that work with previews of Visual Studio 2019. However, in this tutorial we won’t use any previews and only use fully released versions of .NET Core 2 and Visual Studio 2019.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create ASP.NET Core 2.2 REST API
&lt;/h2&gt;

&lt;p&gt;In Visual Studio 2019, create a new project and choose ASP.NET Core Web Application. Name our project (Blog). Then choose .ASP.NET Core 2.2 version and the API template:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fsgoh4c7tiz8kv0ugusnb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fsgoh4c7tiz8kv0ugusnb.png" alt="Create a new ASP.NET Core Web Application prompt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Add models and Entity Framework Database Context
&lt;/h2&gt;

&lt;p&gt;Next up, let’s create a folder called Models, and then add a class file called &lt;strong&gt;BlogPost.cs&lt;/strong&gt;. Make sure to import necessary namespaces.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Then create an API controller — right click the Controllers folder, choose Add -&amp;gt; Controller. Then choose &lt;strong&gt;API controller with actions, using Entity Framework&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Choose BlogPost as Model class.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Under Data context class, press the + button and call the context BlogPostsContext.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ffav08erbc0dgmj9j8z6v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ffav08erbc0dgmj9j8z6v.png" alt="Add API controller with actions prompt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you press Add, Visual Studio will add the necessary NuGet packages and create a new database context, BlogPostContext, in the Data folder. You will also have the BlogPostsController created for you, filled with lots of API methods.&lt;/p&gt;

&lt;p&gt;The contents of &lt;strong&gt;BlogPostsContext.cs&lt;/strong&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The contents of newly created &lt;strong&gt;BlogPostsController.cs&lt;/strong&gt;, our ApiController:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This is fully working code, with route configuration, all CRUD operations and correct HTTP verbs using annotations (HttpPost, HttpGet, HttpPut, HttpDelete). We also force our API to serve JSON, using the &lt;code&gt;[Produces("application/json")]&lt;/code&gt; filter.&lt;/p&gt;

&lt;p&gt;We’re following the best practices for REST APIs, as we use GET for listing data, POST for adding new data, PUT for updating existing data, and DELETE for deleting data.&lt;/p&gt;

&lt;p&gt;Note that the BlogPostContext is &lt;strong&gt;dependency injected&lt;/strong&gt;. This context is used to perform all actions needed for our app’s back-end.&lt;/p&gt;

&lt;p&gt;We can however improve this a little bit, using the Repository design pattern to create a data repository, and inject it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a data repository
&lt;/h2&gt;

&lt;p&gt;Our existing code works, however as applications grow, it’s better to split the logic into different layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Data layer with the data repository that communicates with the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Service layer with services used to process logic and data layer communication.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Presentation layer with only the API controller.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For our application, we will have an API controller which communicates with the data repository. Let’s create the repository.&lt;/p&gt;

&lt;p&gt;Right click the Data folder and create a new interface called IDataRepository. Copy and paste this code into IDataRepository.cs:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Then right click the Data folder again and create a new class called DataRepository. Copy and paste this code into &lt;strong&gt;DataRepository.cs&lt;/strong&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;As you can see, we have dependency injected the BlogPostContext into our DataRepository class.&lt;/p&gt;

&lt;h2&gt;
  
  
  Update BlogPostsController to use the data repository
&lt;/h2&gt;

&lt;p&gt;Replace the code in BlogPostsController with the following:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;You can see the data repository in action in the &lt;code&gt;PutBlogPost&lt;/code&gt;, &lt;code&gt;PostBlogPost&lt;/code&gt; and &lt;code&gt;DeleteBlogPost&lt;/code&gt; methods, like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We however choose to keep our dependency on BlogPostsContext in the controller, using both the context and data repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  CORS in app configuration
&lt;/h2&gt;

&lt;p&gt;In &lt;strong&gt;Startup.cs&lt;/strong&gt;, you already can see some configuration — our app will use MVC and have a db context for instance. Update the ConfigureServices method to look like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Since we’re going to call our REST API from JavaScript, we need to enable CORS. We will use a default policy.&lt;/p&gt;

&lt;p&gt;Also, we register our DataRepository here.&lt;/p&gt;

&lt;p&gt;Make sure to import necessary namespaces.&lt;/p&gt;

&lt;p&gt;Note that we’ve commented out &lt;code&gt;services.AddSpaStaticFiles()&lt;/code&gt;. We will uncomment this when we’ve created the Angular application, but we’re not there yet.&lt;/p&gt;

&lt;p&gt;Then update the Configure method to look like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;code&gt;UseCors&lt;/code&gt; must come before &lt;code&gt;UseMvc&lt;/code&gt; here. Don’t forget to import the necessary namespaces.&lt;/p&gt;

&lt;p&gt;We’ve commented out SPA specific configuration here. We will uncomment &lt;code&gt;app.UseSpaStaticFiles()&lt;/code&gt; and &lt;code&gt;app.UseSpa()&lt;/code&gt; later, when we’ve created our Angular application.&lt;/p&gt;

&lt;p&gt;Let’s also update &lt;strong&gt;launchSettings.json&lt;/strong&gt; to set &lt;code&gt;launchUrl&lt;/code&gt; to empty in two places:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"launchUrl": “”&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Also delete &lt;strong&gt;ValuesController.cs&lt;/strong&gt; in the Controllers folder.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup migrations and create the database
&lt;/h2&gt;

&lt;p&gt;We’re almost there!&lt;/p&gt;

&lt;p&gt;Now that we have the BlogPostsContext and use the code first approach for Entity Framework, it’s time to setup migrations. First, let’s take a look at the database connection string in &lt;strong&gt;appSettings.json&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The connection string was created for us earlier and the app will use SQL Server Express LocalDb. You can, of course, use your own instance of SQL Server instead, just make sure the connection string is correct!&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;To enable migrations, open the Package Manager Console (Tools-&amp;gt;NuGet Package Manager-&amp;gt;Package Manager Console) and run this command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Add-Migration Initial&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We’ll get this message back:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Microsoft.EntityFrameworkCore.Infrastructure[10403]

Entity Framework Core 2.2.6-servicing-10079 initialized 'BlogPostsContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None

To undo this action, use Remove-Migration.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perfect! A Migrations folder is created with your Entity Framework migrations, which will contain changes to the Entity Framework model. We have one migration file, named something like &lt;strong&gt;20190912150055_Initial.cs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this file, we have the &lt;code&gt;Up&lt;/code&gt; and &lt;code&gt;Down&lt;/code&gt; methods, which will upgrade and downgrade the database to the next or previous version.&lt;/p&gt;

&lt;p&gt;To create the database, we now have to execute the following command in the Package Manager Console:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Update-Database&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let’s open the SQL Server Object Explorer (View -&amp;gt; SQL Server Object Explorer). We now have this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F6rkg4z2lc6o2lsbfxs4n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F6rkg4z2lc6o2lsbfxs4n.png" alt="SQL Server Object Explorer view"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember, if you make any changes to the data model, you need to use the &lt;code&gt;Add-Migration YourMigrationName&lt;/code&gt; and &lt;code&gt;Update-Database&lt;/code&gt; commands to push changes to the database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try the API
&lt;/h2&gt;

&lt;p&gt;Press F5 in Visual Studio to start the application. On localhost, browse to &lt;code&gt;/api/blogposts&lt;/code&gt; which should return an empty JSON string. You can now use &lt;a href="https://www.getpostman.com/" rel="noopener noreferrer"&gt;Postman&lt;/a&gt; to create a new blog post.&lt;/p&gt;

&lt;p&gt;Here’s the JSON to post:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "dt": "2019-09-12T18:18:02.190Z",
  "creator": "Martin",
  "title": "Test",
  "body": "Testing"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Postman, make sure the API URL is correct and POST is used as the http verb. Fill in above JSON in the editor (choose raw) and choose JSON (application/json) before you press Send. The request and returned body result should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F9b8d48tprno9o0elv3ah.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F9b8d48tprno9o0elv3ah.png" alt="Postman API POST request with body result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if you change http verb from POST to GET, you’ll now get this result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Foj9rc9xl4qno6gwgb6qm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Foj9rc9xl4qno6gwgb6qm.png" alt="Postman GET body result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our API is up and running!&lt;/p&gt;

&lt;p&gt;Now on to our Angular 8 front-end app. Here's part 2 of the tutorial. &lt;a href="https://dev.to/dileno/build-an-angular-8-app-with-rest-api-and-asp-net-core-2-2-part-2-46ap"&gt;Part 2 is here - Angular 8 app with REST API&lt;/a&gt; &lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>angular</category>
    </item>
  </channel>
</rss>
