<?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>DEV Community: Alex Dhaenens</title>
    <description>The latest articles on DEV Community by Alex Dhaenens (@alexdhaenens).</description>
    <link>https://dev.to/alexdhaenens</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%2F319317%2Fbc4a3fac-cb5c-4ff2-9f69-6a155aca53f4.jpg</url>
      <title>DEV Community: Alex Dhaenens</title>
      <link>https://dev.to/alexdhaenens</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alexdhaenens"/>
    <language>en</language>
    <item>
      <title>Building our own Salesforce SFMC integration with Sitecore Forms</title>
      <dc:creator>Alex Dhaenens</dc:creator>
      <pubDate>Wed, 30 Sep 2020 10:06:50 +0000</pubDate>
      <link>https://dev.to/alexdhaenens/building-our-own-salesforce-sfmc-integration-with-sitecore-forms-2lij</link>
      <guid>https://dev.to/alexdhaenens/building-our-own-salesforce-sfmc-integration-with-sitecore-forms-2lij</guid>
      <description>&lt;p&gt;Some time ago, our Marketing team asked if it was possible to integrate a Sitecore website with Salesforce SFMC. More specifically, they asked if they could add data submitted by some Sitecore Forms to Salesforce Marketing Cloud’s data extensions.&lt;br&gt;
At that time, Sitecore had already several connectors for integrating xDB and the Media Library with SFMC, but no solution specifically for Sitecore Forms. We looked at the possibility to integrate it with Salesforce open APIs.&lt;/p&gt;
&lt;h1&gt;
  
  
  The force is strong with Salesforce
&lt;/h1&gt;

&lt;p&gt;Before continuing further, let me briefly talk about Salesforce, so readers that are not familiar with it understand what I’m talking about.&lt;/p&gt;

&lt;p&gt;Salesforce is a big platform offering quite a lot of SaaS solutions like CRM, Marketing Automation, e-Commerce, etc… In this post I’ll be talking specifically about Salesforce Marketing Cloud, used by marketers. In this software there is something called Data Extensions and is similar to database tables. Each Data Extension has a name and different columns, containing data that can be used in marketing automation workflows. Each DE (data extension) column has a name, a type and several other properties. Records can be added, edited or deleted from a DE.&lt;/p&gt;
&lt;h1&gt;
  
  
  Start of a journey
&lt;/h1&gt;

&lt;p&gt;Although it seemed quite simple at first, the journey wasn’t. Obviously the first thing we did, was to do a little research on what we could use. Firstly we landed on the &lt;a href="https://developer.salesforce.com/docs/atlas.en-us.noversion.mc-apis.meta/mc-apis/index-api.htm" rel="noopener noreferrer"&gt;Salesforce docs&lt;/a&gt; and found out that Salesforce offers an extensive soap and rest API. This definitely offered all the features we required four our project, but as developers we did not want to reinvent the wheel and wanted to see around on the internet if there were some nuget packages available that we could use. That way, we don’t have to write any DAO (data access object) code handling the parsing of the api request data. This was the time we arrived at the &lt;a href="https://github.com/salesforce-marketingcloud/FuelSDK-CSharp" rel="noopener noreferrer"&gt;fuelSDK&lt;/a&gt;, a nuget package that is available under the MIT license.&lt;/p&gt;
&lt;h1&gt;
  
  
  FuelSdk, our savior?
&lt;/h1&gt;

&lt;p&gt;After we found the package, we tested it out, to see if it delivered what we needed. Setting up the package was fairly easy as you just needed to install the package using nuget. The only additional thing developers need to do is to add some configuration to your project’s web config. The configuration exists mostly of api keys and instance urls and looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;configSections&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"fuelSDK"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"FuelSDK.FuelSDKConfigurationSection, FuelSDK"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/configSections&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;fuelSDK&lt;/span&gt;
    &lt;span class="na"&gt;appSignature=&lt;/span&gt;&lt;span class="s"&gt;"none"&lt;/span&gt;
    &lt;span class="na"&gt;clientId=&lt;/span&gt;&lt;span class="s"&gt;"YOUR_CLIENT_ID"&lt;/span&gt;
    &lt;span class="na"&gt;clientSecret=&lt;/span&gt;&lt;span class="s"&gt;"YOUR_CLIENT_SECRET"&lt;/span&gt;
    &lt;span class="na"&gt;authEndPoint=&lt;/span&gt;&lt;span class="s"&gt;"YOUR_AUTH_TSE"&lt;/span&gt;
    &lt;span class="na"&gt;restEndPoint=&lt;/span&gt;&lt;span class="s"&gt;"YOUR_REST_TSE"&lt;/span&gt;
    &lt;span class="na"&gt;useOAuth2Authentication=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt; 
    &lt;span class="na"&gt;applicationType=&lt;/span&gt;&lt;span class="s"&gt;"server"&lt;/span&gt;&lt;span class="err"&gt;||"public"||"web"&lt;/span&gt; &lt;span class="err"&gt;//if&lt;/span&gt; &lt;span class="err"&gt;you&lt;/span&gt; &lt;span class="err"&gt;are&lt;/span&gt; &lt;span class="err"&gt;using&lt;/span&gt; &lt;span class="err"&gt;oauth2&lt;/span&gt; &lt;span class="err"&gt;for&lt;/span&gt; &lt;span class="err"&gt;public&lt;/span&gt; &lt;span class="err"&gt;or&lt;/span&gt; &lt;span class="err"&gt;web&lt;/span&gt; &lt;span class="err"&gt;app.&lt;/span&gt; &lt;span class="err"&gt;By&lt;/span&gt; &lt;span class="err"&gt;default,&lt;/span&gt; &lt;span class="err"&gt;this&lt;/span&gt; &lt;span class="err"&gt;will&lt;/span&gt; &lt;span class="err"&gt;be&lt;/span&gt; &lt;span class="err"&gt;"server"&lt;/span&gt; 
    &lt;span class="na"&gt;authorizationCode=&lt;/span&gt;&lt;span class="s"&gt;"AUTHORIZATION_CODE"&lt;/span&gt;
    &lt;span class="na"&gt;redirectURI=&lt;/span&gt;&lt;span class="s"&gt;"REDIRECT_URI_FOR_PUBLIC/WEB_APP"&lt;/span&gt;
    &lt;span class="na"&gt;accountId=&lt;/span&gt;&lt;span class="s"&gt;"TARGET_ACCOUNT_ID"&lt;/span&gt;
    &lt;span class="na"&gt;scope=&lt;/span&gt;&lt;span class="s"&gt;"DATA_ACCESS_PERMISSIONS"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the configuration is done, you could simply add data to data extensions using this piece of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;deRow&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ETDataExtensionRow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;AuthStub&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;DataExtensionName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataExtensionName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;deRow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ColumnValues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CustomerNumber"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Customer_"&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="n"&gt;deRow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ColumnValues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FirstName"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FirstName_"&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="n"&gt;deRow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ColumnValues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"LastName"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"LastName_"&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;derResponse&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;deRow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AreEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;derResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this piece of code, we are adding values to a dictionary where each entry has as key the column name of the data extension’s column. This is the column we’ll be inserting this data into. The values of the dictionary entries are the actual (string based) data that we’ll be adding.&lt;/p&gt;

&lt;p&gt;So, in order, to reach our goal, which is to add the data from a (Sitecore) form submit to a SFMC Data Extension, we’ll need a Save Action that executes the code above, but adjusted for that specific form and data extension. This means that the keys of the dictionary must be the right column names (no typos allowed!) and that the values should be the value of the right submitted form field. Although it is remarkable easy to use, it is not a silver bullet.&lt;/p&gt;

&lt;h1&gt;
  
  
  Adding more fuel
&lt;/h1&gt;

&lt;p&gt;The first issue, as you may notice, is that although adding this to a single form is easy and fast, adding this to multiple forms isn’t. This is because the shared code can’t be abstracted away. You’ll still need to build that dictionary with the right keys and values (typos not allowed) for each form. Apart from development time you must also consider the fact that this must be tested for each form on each environment which increases the cost a lot. On a side note, it might also take a while between the marketer or client asking for such a form submit action and the moment it is deployed and working on production. This is because you’ll need to follow the full software development cycle (build, test , release).&lt;/p&gt;

&lt;p&gt;The second issue is that it is error prone. If a typo would slip in the code, especially the part of the dictionary (the column names and the field names to be more specific) you can experience massive delays. Not only that , you aren’t guaranteed that the code will work on different environments, as exactly (and when I mean exactly, I mean including the names of the fields)  the same forms are a must on each environment and that is something that is not possible in many cases.&lt;/p&gt;

&lt;p&gt;The last issue is that the above code is not future proof: as soon as a data extension changes it won’t work and neither will it work in the case of a form change (renaming or removing fields). Also, every time you need a change (e.g. a form must change etc) you’ll need to adjust the code to cope with the change and redeploy and test it on all environments.&lt;/p&gt;

&lt;p&gt;For those reasons and because Sitecore is such an open platform that can be easily extended, we’ve decided to experiment with our own Forms extension module. The idea is to build a Sitecore integrated application that does not require any coding nor deploys, is movable between environments and is easily adjustable in Sitecore for non tech savvy users. We will add soon the result of our experiments as a module for the Sitecore community.&lt;/p&gt;

&lt;p&gt;If you are not sure that the module is something for you, I’ll be discussing the many features it brings to the users and developers in my future blogposts!&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxg333m6e65yg9a89j05o.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxg333m6e65yg9a89j05o.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>sitecore</category>
      <category>salesforce</category>
      <category>csharp</category>
      <category>webdev</category>
    </item>
    <item>
      <title>SFMC and its many features</title>
      <dc:creator>Alex Dhaenens</dc:creator>
      <pubDate>Thu, 24 Sep 2020 16:21:08 +0000</pubDate>
      <link>https://dev.to/alexdhaenens/sfmc-and-its-many-features-j70</link>
      <guid>https://dev.to/alexdhaenens/sfmc-and-its-many-features-j70</guid>
      <description>&lt;p&gt;In one of my previous blogposts I discussed why we made our own SFMC Forms extension module based on Salesforce open APIs, a module to make moving data from Sitecore forms to Salesforce Marketing Cloud easier. Feel free to read the blogpost, if you haven’t already. &lt;/p&gt;

&lt;p&gt;At this instant, we are also very happy to announce that the module is released to the public for free and can be &lt;strong&gt;downloaded from &lt;a href="https://github.com/AlexDhaenens/SFMC/"&gt;the git repository&lt;/a&gt;&lt;/strong&gt;. In this blogpost we would like to talk about the many features of the module. During this writing,  we’ll be using the terms developer and content editor. The developer is the person that develops the Sitecore website and therefor also needs to install the module. On the other hand, the content editor denotes either somebody for marketing or the person that is creating content on the Sitecore instance.&lt;/p&gt;

&lt;h1&gt;
  
  
  The easy setup
&lt;/h1&gt;

&lt;p&gt;In order to get your data from Sitecore forms to Salesforce Marketing Cloud, both the developer and content editor need to do several things.&lt;/p&gt;

&lt;p&gt;First of all, the developer needs to download and install the module on the Sitecore instance. After that (s)he needs add some configuration to the web.config. This is the configuration required by FuelSDK and consists of api endpoints and keys. It looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;configSections&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"fuelSDK"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"FuelSDK.FuelSDKConfigurationSection, FuelSDK"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/configSections&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;fuelSDK&lt;/span&gt;
    &lt;span class="na"&gt;appSignature=&lt;/span&gt;&lt;span class="s"&gt;"none"&lt;/span&gt;
    &lt;span class="na"&gt;clientId=&lt;/span&gt;&lt;span class="s"&gt;"YOUR_CLIENT_ID"&lt;/span&gt;
    &lt;span class="na"&gt;clientSecret=&lt;/span&gt;&lt;span class="s"&gt;"YOUR_CLIENT_SECRET"&lt;/span&gt;
    &lt;span class="na"&gt;authEndPoint=&lt;/span&gt;&lt;span class="s"&gt;"YOUR_AUTH_TSE"&lt;/span&gt;
    &lt;span class="na"&gt;restEndPoint=&lt;/span&gt;&lt;span class="s"&gt;"YOUR_REST_TSE"&lt;/span&gt;
    &lt;span class="na"&gt;useOAuth2Authentication=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt; 
    &lt;span class="na"&gt;applicationType=&lt;/span&gt;&lt;span class="s"&gt;"server"&lt;/span&gt;&lt;span class="err"&gt;||"public"||"web"&lt;/span&gt; &lt;span class="err"&gt;//if&lt;/span&gt; &lt;span class="err"&gt;you&lt;/span&gt; &lt;span class="err"&gt;are&lt;/span&gt; &lt;span class="err"&gt;using&lt;/span&gt; &lt;span class="err"&gt;oauth2&lt;/span&gt; &lt;span class="err"&gt;for&lt;/span&gt; &lt;span class="err"&gt;public&lt;/span&gt; &lt;span class="err"&gt;or&lt;/span&gt; &lt;span class="err"&gt;web&lt;/span&gt; &lt;span class="err"&gt;app.&lt;/span&gt; &lt;span class="err"&gt;By&lt;/span&gt; &lt;span class="err"&gt;default,&lt;/span&gt; &lt;span class="err"&gt;this&lt;/span&gt; &lt;span class="err"&gt;will&lt;/span&gt; &lt;span class="err"&gt;be&lt;/span&gt; &lt;span class="err"&gt;"server"&lt;/span&gt; 
    &lt;span class="na"&gt;authorizationCode=&lt;/span&gt;&lt;span class="s"&gt;"AUTHORIZATION_CODE"&lt;/span&gt;
    &lt;span class="na"&gt;redirectURI=&lt;/span&gt;&lt;span class="s"&gt;"REDIRECT_URI_FOR_PUBLIC/WEB_APP"&lt;/span&gt;
    &lt;span class="na"&gt;accountId=&lt;/span&gt;&lt;span class="s"&gt;"TARGET_ACCOUNT_ID"&lt;/span&gt;
    &lt;span class="na"&gt;scope=&lt;/span&gt;&lt;span class="s"&gt;"DATA_ACCESS_PERMISSIONS"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whenever this configuration is added to the web.config, the module is ready to use. This is the moment where the developer’s job is done (yes for real!) and (s)he can continue working on other exciting stuff.&lt;/p&gt;

&lt;p&gt;This is also the moment that the content editor’s work begins. First of all (s)he needs to add the ”Send to SFMC” to the form that needs to send its data to SFMC. The next step is to create a binding between a form and a data extension to then publish it. This can be done by the handcrafted SFMC save actions dashboard application. &lt;/p&gt;

&lt;h1&gt;
  
  
  A Sitecore integrated UI
&lt;/h1&gt;

&lt;p&gt;When a content editor wants to create or edit an SFMC binding, (s)he can open the dashboard application in Sitecore. When the application is opened it will display a UI showing a list of configured bindings. This looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--boZevtpA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9s5fcikk2b5g5f3hj3wy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--boZevtpA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9s5fcikk2b5g5f3hj3wy.png" alt="Bindings list" width="880" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can clearly see, this is a very intuitive UI fully integrated inside Sitecore and therefor the content editor will use the same UX experience as other standard Sitecore modules.&lt;/p&gt;

&lt;p&gt;This page has several buttons, to create, update, publish or delete a binding. If a CE (content editor) creates or updates a binding, a page like this will be displayed:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gSbMj1u6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a5famqq5hw37iz1lwcrg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gSbMj1u6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a5famqq5hw37iz1lwcrg.png" alt="Create or edit a binding" width="880" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again, this UI is very intuitive and has a full Sitecore look and feel.&lt;/p&gt;

&lt;h1&gt;
  
  
  Fully fetched data
&lt;/h1&gt;

&lt;p&gt;When creating or editing a binding, you’ll see just as in the image above, that all the data that needs to be used is fetched either from Sitecore or Salesforce. That data is then displayed in a drop down. This serves several purposes, firstly no names and ids need to be remembered and therefor mistakes and typos can’t be made. This also greatly increases speed.&lt;/p&gt;

&lt;p&gt;There are several things a CE needs to choose for each binding, firstly the form the data is coming from as well as the data extension the data is going to. This can be done with the beforementioned dropdowns. When those two are chosen, a CE can choose to trigger an event in SFMC.&lt;/p&gt;

&lt;p&gt;As soon as a form and a DE (data extension) are chosen, the UI will fetch respectively the form fields as well as the data extension columns. Those will be displayed in the UI as well. For each DE column, a row will be shown with the name as well as a dropdown with different fields to choose from (including the fetched form fields).&lt;/p&gt;

&lt;h1&gt;
  
  
  Lots of fields to choose from
&lt;/h1&gt;

&lt;p&gt;As soon as the UI is loaded with the DE columns and form fields a CE can choose for each DE column a field. Those so-called fields are displayed in a dropdown. There are many fields to choose from and because there are so many, we’ve grouped them in different categories.:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jvxbEIme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pzrwkz3g74lu250f544p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jvxbEIme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pzrwkz3g74lu250f544p.png" alt="Lots of fields" width="880" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first group, “form fields” consist of all the fields from the form. When such a field is picked, the value that the website user provided for that field will be send to SFMC. Another group is the “calculated fields” group. This group consist of different values that do not originate from a form such as the website language, a random GUID or timestamp and many more. The last two groups are groups for xdb related data.&lt;/p&gt;

&lt;h1&gt;
  
  
  Migrating configuration
&lt;/h1&gt;

&lt;p&gt;As soon as you save a new binding an item will be created in the master database in Sitecore. Whenever you are ready to go live with the binding, you can publish either the item in the Sitecore tree or use the publish button in the dashboard application.&lt;/p&gt;

&lt;p&gt;Since all the bindings are Sitecore items, you can migrate bindings between different environments by simply packaging those items and installing them on the desired environment. This also means that you do not need to recycle, nor do you need to redeploy anything when migrating data.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;As you can clearly see, this module is easy to install and to use. It was such a cool experience to develop this module using Sitecore and Salesforce APIs that we made it available to the community. So feel free to use it!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Kq-eV5t4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/i4w1qoqdqkrh45z4bgyg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Kq-eV5t4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/i4w1qoqdqkrh45z4bgyg.png" alt="Alt Text" width="225" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>sitecore</category>
      <category>salesforce</category>
      <category>webdev</category>
      <category>csharp</category>
    </item>
    <item>
      <title>How to execute shell commands in js</title>
      <dc:creator>Alex Dhaenens</dc:creator>
      <pubDate>Wed, 26 Aug 2020 10:06:00 +0000</pubDate>
      <link>https://dev.to/alexdhaenens/how-to-execute-shell-commands-in-js-2j5j</link>
      <guid>https://dev.to/alexdhaenens/how-to-execute-shell-commands-in-js-2j5j</guid>
      <description>&lt;p&gt;For one of my side projects, I needed to be able to execute certain shell commands with JavaScript. That project is an Electron–React project, in which – thanks to the Electron framework – I have &lt;em&gt;full access to the Node.js API&lt;/em&gt; and therefor the Node.js runtime. For the readers that are interested in Electron or in combining Electron and React you can find my blogs on those topics respectively &lt;a href="https://dev.to/alexdhaenens/electron-the-future-18nc"&gt;here&lt;/a&gt; and &lt;a href="https://dev.to/alexdhaenens/electron-and-react-a-successful-marriage-ncf"&gt;here&lt;/a&gt;. &lt;br&gt;
Although it is possible to execute shell commands in JavaScript, there are two important remarks: first that &lt;strong&gt;executing shell commands uses the Node.js API&lt;/strong&gt;, so be aware that it only works in an environment that has access to that API (meaning a normal browser runtime won’t work). Secondly, &lt;strong&gt;some shell commands require administration permissions&lt;/strong&gt;, so in those cases you’ll need to make sure that the process running your JavaScript code has such permissions.&lt;/p&gt;
&lt;h1&gt;
  
  
  The API
&lt;/h1&gt;

&lt;p&gt;The Node.js API has a module called &lt;a href="https://nodejs.org/api/child_process.html#child_process_child_process"&gt;child_process&lt;/a&gt; that offers functions to spawn child processes both in ansynchronous as asynchronous manner. One of those functions that are available is the &lt;em&gt;exec function&lt;/em&gt;. It has the following signature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="p"&gt;[,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;][,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the parameters: &lt;em&gt;command&lt;/em&gt; as a string, &lt;em&gt;options&lt;/em&gt; as an object with various options (see the &lt;a href="https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback"&gt;documentation&lt;/a&gt; for more information) and a &lt;em&gt;callback function&lt;/em&gt;. The function itself returns a reference to the spawned process (but it is not needed for executing shell commands).&lt;/p&gt;

&lt;p&gt;With the &lt;em&gt;exec&lt;/em&gt; function we can create a custom function with two different callbacks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;exec&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;child_process&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;executeCommand&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;successCallback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;errorCallback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="c1"&gt;// console.log(`error: ${error.message}`);&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errorCallback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;errorCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;//console.log(`stderr: ${stderr}`);&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errorCallback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;errorCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;//console.log(`stdout: ${stdout}`);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;successCallback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;successCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although not required, using such a function is much handier and cleaner as you can use a different callback functions for success and error. In addition, there is a single point where you can turn on or off logging for all your commands.&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating command functions
&lt;/h1&gt;

&lt;p&gt;Since we got our base function for executing commands we can create now different functions for the different commands the code needs to execute. Depending which operating system you are targeting, it can be possible that other (shell)commands are needed (e.g. the &lt;em&gt;dir&lt;/em&gt; command on windows and the &lt;em&gt;ls&lt;/em&gt; command on linux). For the sake of an example you can get the current git branch with the following git command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git &lt;span class="nt"&gt;-C&lt;/span&gt; “folder” rev-parse &lt;span class="nt"&gt;--abbrev-ref&lt;/span&gt; HEAD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can create a custom function for this, accepting a folder and two callbacks to execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getGitBranchCommand&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;folder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;executeCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`git -C &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;folder&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; rev-parse --abbrev-ref HEAD`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;branch&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;branch&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;errormsg&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errormsg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This functino will either call the &lt;em&gt;success&lt;/em&gt; callback with the output of the shell command (which is the branch name) or call the &lt;em&gt;error&lt;/em&gt; callback with the message the command returned when failing.&lt;/p&gt;

&lt;p&gt;Some shell commands print a lot of text to the stout stream, so for those commands you’ll need to apply a regex to parse the data you want from that output.&lt;/p&gt;

&lt;h1&gt;
  
  
  Combining with state frameworks
&lt;/h1&gt;

&lt;p&gt;A lot of applications use a state framework to keep the current state of your app. Chances are that you, the reader, use such a framework in your project and you’ll want to store the result of the commands you executed in that state. In my example I’m using &lt;a href="https://redux.js.org/"&gt;Redux&lt;/a&gt; but you can follow a similar approach for other frameworks. &lt;br&gt;
By using the &lt;em&gt;getGitBranchCommand&lt;/em&gt; shown above you can create a new function specific for the Redux framework:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getGitBranch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;folder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;getGitBranchCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;folder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;branch&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setFocusProjectGitBranch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;branch&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have a function that accepts a folder and the dispatch function (needed for dispatching actions in redux). This function can now be used anywhere in your application. In the code snippet above I’ve used the &lt;em&gt;setFocusProjectGitBranch&lt;/em&gt; function, which is an action creator (if you don't know what that is, no worries it is Redux specific). Also, on a side node, the error callback is an empty function since I don’t need the error message (yet).&lt;/p&gt;

&lt;h1&gt;
  
  
  Architecture summary
&lt;/h1&gt;

&lt;p&gt;I would like to summarize the blogpost by discussing the architecture used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;getGitBranch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;folder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;getGitBranchCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;folder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;executeCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;successCallback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;errorCallback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="p"&gt;[,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;][,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;em&gt;executeCommand&lt;/em&gt; is a general function for executing any command using the &lt;em&gt;exec&lt;/em&gt; function from the &lt;strong&gt;child_processes node module&lt;/strong&gt;. That function is used by the &lt;em&gt;getGitBranchCommand&lt;/em&gt;, a function specific designed for getting the git branch. Lastly the highest function, is the one exposed to my whole application and is a state management framework dependent function. It executes the earlier mentioned &lt;em&gt;getGitBranchCommand&lt;/em&gt; function and stores the result in the state, by using the state management’s api.&lt;/p&gt;

&lt;p&gt;Using this architecture has the benefit that, when you would reuse the code in another project but with another state management framework, you only need to replace the &lt;em&gt;getGitBranch function&lt;/em&gt;. Additionally, if you would for example support other operating systems, which could require different commands to do the same thing, you’ll only need to replace the &lt;em&gt;getGitBranchCommand&lt;/em&gt; function.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>node</category>
    </item>
    <item>
      <title>How to pass rendering parameters from Sitecore to React</title>
      <dc:creator>Alex Dhaenens</dc:creator>
      <pubDate>Wed, 05 Aug 2020 10:01:21 +0000</pubDate>
      <link>https://dev.to/alexdhaenens/how-to-pass-rendering-parameters-from-sitecore-to-react-4m1n</link>
      <guid>https://dev.to/alexdhaenens/how-to-pass-rendering-parameters-from-sitecore-to-react-4m1n</guid>
      <description>&lt;p&gt;For some of your projects you’ll probably have a &lt;strong&gt;Sitecore component with a React app&lt;/strong&gt;. Such a component normally doesn't have much logic inside your controller action, since this component only renders a container (div) element.  There might also be a script tag in your view, with your React application script, but this depends on your setup. This is often the only job your Sitecore component has to do, because all the rest is handled in the front-end. &lt;br&gt;
Such components make it possible to create advanced components that are a hassle to do in the backend while still making the application user-friendly. However, by using this approach some features of the Sitecore framework are lost: passing rendering parameters, personalization ,...&lt;/p&gt;
&lt;h1&gt;
  
  
  Why do you want it?
&lt;/h1&gt;

&lt;p&gt;Rendering parameters of a Sitecore component offer a great way to change the presentation and/or functionality of a certain component by adjusting those parameters. Sitecore also made it pretty easy to create custom rendering parameters, a topic that has a lot of blogposts covering it. For that reason explaining on how to do it is out of scope of this blogpost.&lt;/p&gt;

&lt;p&gt;Personalization is a big feature in Sitecore that enables the content editors to create rules to e.g. hide or show components, adjust the datasource,... Rendering parameters can be used in combination with personalization: by adding a certain component twice with different rendering parameter values and then hide or show the components with personalization rules.&lt;/p&gt;

&lt;p&gt;Using those rendering parameters in the back-end is fairly easy. The only issue rises when you want to pass them to your React based Sitecore component. One could create an api to pass them, but you don't want to introduce additional latency and the parameter values should already be known when the app starts.&lt;/p&gt;
&lt;h1&gt;
  
  
  Passing the parameters: backend
&lt;/h1&gt;

&lt;p&gt;The key to passing the rendering parameters is the html &lt;a href="https://www.w3schools.com/tags/att_data-.asp"&gt;data attribute&lt;/a&gt;. The idea is quite simple: you &lt;strong&gt;add your rendering parameters as data attributes to the container&lt;/strong&gt; (div) inside your (Razor) view and let your React application read them when the app starts.&lt;/p&gt;

&lt;p&gt;In order to do this you’ll need to pass the parameters you require from your controller action to your view by using the view model, this is pretty straight forward. Then you’ll pass those parameters as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="err"&gt;=”&lt;/span&gt;&lt;span class="nc"&gt;reactapp1&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;renderingparameter1&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="n"&gt;value1&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;renderingparameter2&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="n"&gt;value2&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can freely choose a name for your data attribute but, &lt;br&gt;
as this is the HTML specification, there are two rules you need to follow:&lt;br&gt;
1)  A prefix of “data-“&lt;br&gt;
2)  No uppercase letters&lt;/p&gt;
&lt;h1&gt;
  
  
  Reading the parameters: front end
&lt;/h1&gt;

&lt;p&gt;The next step is to read them in your React application when it starts and (preferably) store them in state. Reading them is quite easy! You just need to add following code to  your application’s entry point, which is the js file where the ReactDOM.render is used to render your application into your container div. You can read the data attributes like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;renderingparams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;renderingparameter1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;renderingparameter1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;renderingparameter2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;renderingparameter2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The container variable in the above code example denotes a variable holding a reference to your container DOM element. You should already have such a variable since you need it for rendering your app with ReactDOM.render. If you are passing data types other then strings you might want to parse them first. You can do this for respectively booleans and numbers like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;renderingparameter1&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="nx"&gt;True&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;
    &lt;span class="nb"&gt;parseInt&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;renderingparameter1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might also want to consider using a default value when a data attribute can’t be found or parsed.&lt;/p&gt;

&lt;p&gt;The next step is to pass them to your application as prop for example like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="na"&gt;renderingparams&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;renderingparams&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="err"&gt;..&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
…
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your rendering parameters are now fully available inside your React application. I would recommend saving those parameters in your app state (by for example using context, Redux, Mobx) so you can access them everywhere that is needed without passing them as props. As this is application dependent, I’ll leave this task up to the developer.&lt;/p&gt;

&lt;h1&gt;
  
  
  Personalization
&lt;/h1&gt;

&lt;p&gt;When you have the aforementioned structure in place, you can now personalize the component by adjusting the rendering parameters. Additionally, you can also pass personalization data to your React applications: by using the data attributes to pass xconnect data to your app. &lt;/p&gt;

</description>
      <category>react</category>
      <category>sitecore</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>React Summit Amsterdam, my takeaways</title>
      <dc:creator>Alex Dhaenens</dc:creator>
      <pubDate>Thu, 14 May 2020 11:22:57 +0000</pubDate>
      <link>https://dev.to/alexdhaenens/react-summit-amsterdam-my-takeaways-460</link>
      <guid>https://dev.to/alexdhaenens/react-summit-amsterdam-my-takeaways-460</guid>
      <description>&lt;p&gt;A small month ago, a major React conference would have taken place in Amsterdam: React Summit Amsterdam. This would’ve been my very first conference in my professional life I would’ve attended. But, as you can guess, due to the global pandemic it was cancelled. Luckily  to us, the organizers did a great job and hosted a virtual event at that same date the real event would have been hosted. Aside from that, a replacement conference will be held in September (if all goes well). &lt;/p&gt;

&lt;p&gt;In the virtual event many different speakers did discuss many different topics, a full list of the speakers can be found &lt;a href="https://remote.reactsummit.com/"&gt;here&lt;/a&gt;. The event was livestreamed on Youtube, meaning that I could attend the summit from the comfort of my pj’s and sofa. At the moment of writing, some time to reflect has passed and I can now say what really kept hanging in my brain. There are four talks that really stayed: The &lt;em&gt;Mystery talk&lt;/em&gt; by &lt;strong&gt;Guillermo Rauch&lt;/strong&gt;, &lt;em&gt;Controlling apps&lt;/em&gt; by &lt;strong&gt;Vladimir Novick&lt;/strong&gt;, &lt;em&gt;AHA programming&lt;/em&gt; by &lt;strong&gt;Kent C. Dodds&lt;/strong&gt; &amp;amp; &lt;em&gt;React Query&lt;/em&gt; by &lt;strong&gt;Tanner Linsey&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Mystery Talk – Guillermo Rauch
&lt;/h1&gt;

&lt;p&gt;Guillermo, from the company Zeit.now, started his talk about speed of websites and webapplications. His point was that at the end, static sites are still the fastest sites, since no time is needed for the backend to render the page. Then he continued by talking about JAM stack (&lt;a href="https://jamstack.org/"&gt;https://jamstack.org/&lt;/a&gt;), which is a new way of building web sites &amp;amp; - applications. The general idea is to prerender sites (to static html’s) and enhance them with Javascript and API’s. He then concluded his talk with talking about his company, Zeit.now. Aside from obviously promoting the company, he explained that the idea he discussed earlier is actually what the company does, combined with a CI/CD.&lt;/p&gt;

&lt;p&gt;I was quite impressed by the structure of his talk (starting with something seemingly random and then building up) combined the passion with he was talking.&lt;/p&gt;

&lt;h1&gt;
  
  
  Controlling apps - Vladimir Novick
&lt;/h1&gt;

&lt;p&gt;Vladimir started his talk with the brain and its magnificence. He followed his introduction with talking about brain waves &amp;amp; how you can measure them: using those headsets with nods that measure activity at some points on your skull. He then showed that more consumer friendly and less complicated Bluetooth headsets (for measuring brain activity) are available at a reasonable price. Since the modern browsers do have a Bluetooth API available to the developers, he reasoned, you could control your website or application with your brain. This can be done by using the Bluetooth API to read values from the headset. He then put his money where his mouth was by showing a demo. In that demo, he was interacting (scrolling, …) with a page with his brain. Lastly, he went a step further to integrating the headset with a drone, so he could fly a drone with his brain. &lt;/p&gt;

&lt;p&gt;I did have to say that it was a very impressing talk in the perspective of future technologies and what is possible right now. It was just quite annoying that he had a poor internet connection and a lot of lagging occurred.&lt;/p&gt;

&lt;h1&gt;
  
  
  AHA programming – Kent C. Dodds
&lt;/h1&gt;

&lt;p&gt;This talk started by showing the attendees a piece of code, written in Javascript. It contained a function and certain places that that function is used. Kent stated that most of the time code starts like this: clean and great code. But as time and the development progresses, the need arises for a similar function. &lt;/p&gt;

&lt;p&gt;Just as all developers have learned, abstraction is the way to go, so Kent added some additional parameters in his function. In his function he then uses an if structure to alter the behavior of the function based on that additional parameter. This way, he told, all the code is reused and the if is then used for the small differences. Again, after some time, he deducted, a new developer starts working on the project and the same time the need for again something similar rises. Obviously, the new developer sees the function and adds another parameter to that function for abstraction purposes. &lt;/p&gt;

&lt;p&gt;Although it still worked, Kent pleaded, this piece of code now introduces many issues: First one, by adding parameters the developers created additional test cases. But to make those tests good all possible combinations of those parameters need to be tested and only very few combinations are used. The next issue Kent pointed was that this piece of code will never be altered, because every time something must change the dev will only add lines to that function. This is because the high complexity and nobody know what and where it is used. The last issue the talked about was that the clean code had become a weird piece of spaghetti code.&lt;/p&gt;

&lt;p&gt;Kent offered a solution to this with a quote: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Code duplication over lousy abstraction&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Which summarizes the ideology that it is not bad to have some duplicated code, because making lousy abstractions is worse. Although abstraction is very important, you should first duplicate the code and adjust it accordingly to the place it is needed and then abstract the common pieces. Most of the time you’ll find out that only very few things are common.&lt;/p&gt;

&lt;p&gt;I do have to say that really liked this talk, as it was very clear framework agnostic and very well put together.&lt;/p&gt;

&lt;h1&gt;
  
  
  React Query - Tanner Linsey
&lt;/h1&gt;

&lt;p&gt;This talk started with a small application, that had some state and some API’s for fetching some data. Tanner used that simple application to show the idea of managing the data querying using React Query (especially the hook). He did this by adjusting the small application and explaining it accordingly. &lt;/p&gt;

&lt;p&gt;After this talk, I really had the feeling that this could help me out a lot although I don’t remember a lot of technical details. &lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Although a remote, virtual conference is different than a real one, it still is a great solution for the quarantine problem. But it only works if the both the attendees and the speakers have a good internet connection. After the couple weeks that past, only a very few things kept hanging in my brain: JAMstack with Zeit.now, you can use brainwaves in your (web) applications, Ken’s ideology  “Code duplication over lousy abstraction” and lastly React Query for managing data querying.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Electron and React, a successful marriage?</title>
      <dc:creator>Alex Dhaenens</dc:creator>
      <pubDate>Thu, 16 Apr 2020 10:08:22 +0000</pubDate>
      <link>https://dev.to/alexdhaenens/electron-and-react-a-successful-marriage-ncf</link>
      <guid>https://dev.to/alexdhaenens/electron-and-react-a-successful-marriage-ncf</guid>
      <description>&lt;p&gt;In one of my previous &lt;a href="https://dev.to/alexdhaenens/electron-the-future-18nc"&gt;posts&lt;/a&gt;, I talked (or rather wrote) about a framework called &lt;a href="https://www.electronjs.org/"&gt;Electron&lt;/a&gt;, which offers the possibility to &lt;em&gt;create cross-platform desktop applications with HTML, CSS and JavaScript&lt;/em&gt;. As soon I saw it, I had to try it out! The first thing I asked myself, though, after I created my first Electron app was: &lt;strong&gt;since Electron displays web pages can I use other JavaScript frameworks (such as React) to build and render my web pages?&lt;/strong&gt; The answer is &lt;strong&gt;YES&lt;/strong&gt;, and as it turns out combining both offers amazing opportunities!&lt;/p&gt;

&lt;h1&gt;
  
  
  Short recap
&lt;/h1&gt;

&lt;p&gt;In my blogpost about Electron, I explained that Electron uses a so-called &lt;strong&gt;main process to display GUI’s&lt;/strong&gt;. Each GUI renders a web page (could be an external link or an html file inside your project). &lt;strong&gt;Web pages are run in separate, isolated processes called renderer processes&lt;/strong&gt;. Electron offers &lt;strong&gt;IPC&lt;/strong&gt; (inter process communication) to send messages between the main &amp;amp; renderer processes. Another nice feature is that the &lt;strong&gt;full Node.js API is exposed by Electron&lt;/strong&gt; in both the main as the renderer processes.&lt;/p&gt;

&lt;h1&gt;
  
  
  Enter React
&lt;/h1&gt;

&lt;p&gt;Electron displays a web page inside a GUI. As a developer you must provide the link to that web page, that page is (often) a static html page inside your project folder. There you can add your React script &amp;amp; container and as soon as the page is displayed, your React app will start. &lt;strong&gt;Your React application runs therefor in the renderer process&lt;/strong&gt;. This is also the same if you would use any other framework (e.g. angular).&lt;/p&gt;

&lt;p&gt;As I discussed in the recap, you can communicate between the main and renderer process(es). This provides the developers &amp;amp; software engineers with endless possibilities, since your React runs in that renderer process. For example, &lt;em&gt;you can create a menu in the native window (runs in the main process) and when a certain menu item is clicked, the React app (runs in the renderer process) navigates to a certain page&lt;/em&gt;. This is done by using the IPC to send a message from the main process to the renderer process, telling which page to go to. This is amazing!&lt;/p&gt;

&lt;p&gt;Because Electron makes it possible to use the full Node.js API in both the main as renderer process, it is possible to let &lt;strong&gt;React use the Node.js API&lt;/strong&gt;. This also provides amazing opportunities, since your React app can now use any Node module. This opens many, many doors: making the React app executing bash scripts on the user's computer, reading from or writing to the user's filesystem, ...&lt;/p&gt;

&lt;h1&gt;
  
  
  Tons of boilerplates
&lt;/h1&gt;

&lt;p&gt;Although &lt;strong&gt;setting up a brand-new Electron-React project is not that much work&lt;/strong&gt;, there are however a lot of things that developers might require or desire for each project: hot reloading, linting and the usage of certain plugins. Setting those up for each project can be cumbersome and time consuming. Luckily for us, there are &lt;strong&gt;amazing boilerplates out there for an Electron-React project&lt;/strong&gt;. The Electron documentation contains a &lt;a href="https://www.electronjs.org/docs/tutorial/boilerplates-and-clis"&gt;list of recommended ones&lt;/a&gt;. Most of those boilerplates are open source so,you can help them improve if you would like.&lt;/p&gt;

&lt;h1&gt;
  
  
  My opinion
&lt;/h1&gt;

&lt;p&gt;In my free time I’m currently building an Electron-React application and so far, I’ve liked combining them very much. Although initially it was a challenge to figure out how Electron works, especially in combination with React. I’ve used a boilerplate that has all the features I require for developing (hot reloading, linting, Sass compiler, …) so I did not have to set them up myself. In my experience it is a fast way of developing desktop applications. &lt;/p&gt;

&lt;p&gt;There is also another, less obvious benefit: you can actually create a React application and host it online but also build a desktop version with the same source code by using Electron. You don’t have to rewrite anything, only setting up the Electron-React project might take some time. &lt;strong&gt;The same React application code can be used without any modifications&lt;/strong&gt;. You can even go further, you could add additional desktop specific features (adding a menu,…) or change the behavior on desktop (saving user preferences,…) with the same code. Since this uses Electron, it is important to note that the &lt;strong&gt;performance issues introduced by Electron will also rise here.&lt;/strong&gt; Therefor, picking the right technologies for a project is still an important task that must be done before starting.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Electron, the future?</title>
      <dc:creator>Alex Dhaenens</dc:creator>
      <pubDate>Fri, 10 Apr 2020 11:02:16 +0000</pubDate>
      <link>https://dev.to/alexdhaenens/electron-the-future-18nc</link>
      <guid>https://dev.to/alexdhaenens/electron-the-future-18nc</guid>
      <description>&lt;p&gt;For some time, I've been hearing things about the &lt;a href="https://www.electronjs.org/"&gt;Electron framework&lt;/a&gt;. It always sounded interesting, but the moment I heard that Visual Studio Code is actually an Electron application, it really took my attention. So, it speaks for itself that I wanted to try it out! &lt;/p&gt;

&lt;h1&gt;
  
  
  What is it?
&lt;/h1&gt;

&lt;p&gt;According to their site, with Electron you can &lt;em&gt;Build cross-platform desktop apps with JavaScript, HTML, and CSS&lt;/em&gt;. And that fully summarizes what it does. Electron does this by combining Chromium &amp;amp; node into a single runtime. It also provides extensive documentation on how to start &amp;amp; use their API's.&lt;/p&gt;

&lt;p&gt;What Electron does is create a native window that loads a certain HTML page, where you can unleash the full power of HTML, CSS and JavaScript. Because  this is actually a web page and the framework uses Chromium, &lt;strong&gt;it can display the full blown dev tools&lt;/strong&gt; (like you are used to in Chrome), and when I say  full blown, I mean you can do everything you can do in the normal dev tools. As you can clearly see that is very useful!&lt;/p&gt;

&lt;h1&gt;
  
  
  The basics
&lt;/h1&gt;

&lt;p&gt;One of the core concepts in Electron is the &lt;strong&gt;principle of the main and the renderer processes&lt;/strong&gt;. The main process is the process that runs a script which display GUI's (where each GUI renders a web page). &lt;em&gt;There can only be one main process!&lt;/em&gt; Each web page then runs in a separate process, called renderer processes. This means that if you have multiple web pages concurrently running in your Electron app, multiple renderer processes are running as well.&lt;/p&gt;

&lt;p&gt;There is a significant difference between the main &amp;amp; renderer processes. The renderer process only manages the web page it displays and is fully isolated. The main process however manages the renderer processes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Electron also provides IPC&lt;/strong&gt; (inter process communication) so the main process can communicate with renderer processes and vice versa by sending messages. This opens many doors, especially since it is inherently unsafe to call native GUI’s from web pages. You can use the IPC to send the message from the web page (running a renderer process) to the main process, which can call native GUI’s.&lt;/p&gt;

&lt;p&gt;As Electron runs on Node.js, it also provides &lt;strong&gt;full access to the Node.js API&lt;/strong&gt;, meaning you can use all your npm packages! And the breath-taking thing here is that the full Node.js API is exposed to both the main as renderer processes. This means that you can for example create or delete files, read them or write to them directly from your web page!&lt;/p&gt;

&lt;h1&gt;
  
  
  Boilerplates and CLI’s
&lt;/h1&gt;

&lt;p&gt;Electron does &lt;strong&gt;not provide one way to build, create or package your Electron apps&lt;/strong&gt;. Instead it uses a rather &lt;strong&gt;modularized approach&lt;/strong&gt;: different tools &amp;amp; cli’s do different tasks and it is up to the developer to pick the preferred ones and combine them into a pipeline that fits his or her needs. &lt;a href="https://www.electronjs.org/docs/tutorial/boilerplates-and-clis"&gt;Electron’s documentation&lt;/a&gt; also lists recommended cli’s for different tasks.&lt;/p&gt;

&lt;p&gt;On the other hand, it is also &lt;em&gt;possible to use a boilerplate&lt;/em&gt;. This is a prefabricated, clean project where everything is already setup and ready to use. Most of the time they are repositories where you clone or copy the code. Since a boilerplate is a ready-to-use project, developers can freely remove or add things (frameworks, tools, …) from or to the project. For example, if a boilerplate uses a certain framework they don’t like, they can just remove it. Boilerplates are rather a starting point for a project and are very great for developers that require certain features (hot reloading, …) in their dev environment and they don’t want to waste time setting those up. Electron provides also &lt;a href="https://www.electronjs.org/docs/tutorial/boilerplates-and-clis"&gt;a list of different recommended boilerplates&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Concerns
&lt;/h1&gt;

&lt;p&gt;For the moment, my only concern is the performance especially compared to a compiled application. I didn’t see any issues nor did I have experienced some in my current Electron apps, but I do think that there will be for apps that do require a (very) high performance. But since performance is a very important topic, the documentation of Electron dedicated a &lt;a href="https://www.electronjs.org/docs/tutorial/performance"&gt;full page&lt;/a&gt; to fixing performance if you would have any issues.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;At the time of writing I do think that there is a big future in Electron as it opens many doors to write apps on different platforms really, really fast! But I'm a bit reserved with the performance, but this should not be an issue with the gross of the applications. What are your thoughts?&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>My first hackathon takeaways</title>
      <dc:creator>Alex Dhaenens</dc:creator>
      <pubDate>Tue, 10 Mar 2020 10:53:12 +0000</pubDate>
      <link>https://dev.to/alexdhaenens/my-first-hackathon-takeaways-ecf</link>
      <guid>https://dev.to/alexdhaenens/my-first-hackathon-takeaways-ecf</guid>
      <description>&lt;p&gt;Earlier this month I did, for the first time in my life, a hackathon and I liked it! The one I did participate in was the &lt;em&gt;Sitecore hackathon 2020&lt;/em&gt;. Although I did not expect it, I did learn a lot. What is more surprising, is that I learned more non-technical than technical things.&lt;/p&gt;

&lt;h1&gt;
  
  
  The hackathon
&lt;/h1&gt;

&lt;p&gt;The Sitecore Hackathon 2020 had the following setup: The organizers would release a couple categories at midnight. From that point in time you had 24h to fully create something in one of the categories. The deliverables should include: A package for installation, an extensive installation manual, documentation and a demo. Each team received a (public) git repo to push your code into.&lt;/p&gt;

&lt;h1&gt;
  
  
  What I learned
&lt;/h1&gt;

&lt;p&gt;Besides from technical stuff and things about myself, this is what I've learned during this hackathon.&lt;/p&gt;

&lt;h2&gt;
  
  
  24h is long, very long
&lt;/h2&gt;

&lt;p&gt;24h is a lot of time especially when you are coding almost non-stop. What I noticed is that &lt;strong&gt;I needed some breaks&lt;/strong&gt;, both mental and physical. What I've also noticed that I was &lt;strong&gt;tired at the end&lt;/strong&gt;, so my mood wasn't exactly &lt;em&gt;ecstatic&lt;/em&gt;. The last thing I noticed is that the &lt;strong&gt;quality of my code lowered at the end&lt;/strong&gt;. So &lt;em&gt;perhaps&lt;/em&gt; it is not a great idea to code non stop for a longer periods of time (or even worse, for multiple days) especially if you need to deliver a high quality, production ready, product.&lt;/p&gt;

&lt;h2&gt;
  
  
  24h is short, very short
&lt;/h2&gt;

&lt;p&gt;On the other hand, I've also noticed that 24h doesn't give you that much time to deliver something amazing! From the 24h you need to at least &lt;strong&gt;extract 2h for testing, writing docs, capturing a demo,....&lt;/strong&gt; Then you need to extract at &lt;strong&gt;least 2-3h for breaks and eating&lt;/strong&gt;, since your brain and body do require it. Then you'll also need to &lt;strong&gt;remove at least 1h-2h of brainstorming time&lt;/strong&gt;, since you and the team need to think about what to build. This leaves &lt;strong&gt;maximum 17h of time to actually code&lt;/strong&gt; and that is not much! And before you know it the deadline is there! I think that the same can be said over sprints, although they are between 2 weeks and a month long, you still are timeboxed and you can't work the whole sprint every second of your working day on the product (you still would have meetings, coffee &amp;amp; toilet breaks).&lt;/p&gt;

&lt;h2&gt;
  
  
  A good mvp is key
&lt;/h2&gt;

&lt;p&gt;In the limited time you have, I've noticed that you need a good basic mvp (e.g. the basic site) as fast as possible so then there is time later on for more advanced, fancy &amp;amp; buzz killing features. This is because a solution with fancy features but that does not have the basics working won't get you there. Don't get me wrong, you need the fancy features to win or at least stand out but your basics should work. Therefor, I believe, the focus should be to deliver a mvp fast to spend the remainder of the time on the fancy features. I also think that a parallel can be drawn to the real world: a good product has fancy stuff but has the basics working!&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the mvp on expertise
&lt;/h2&gt;

&lt;p&gt;As I explained earlier you need a good working mvp and some great fancy killer features. Because you need the mvp first before the fancy features, you need it ready asap. The best way to do this, is to decide to build it in your field expertise. This means that (almost) no risk is involved and therefor the mvp can be delivered on time. For example, if your team's expertise is building React SPA (single page applications), it would be a great benefit to build the mvp in React as a SPA. Since your team does this all day, it wouldn't take long to deliver something mvp worthy fast and without any risks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do risky stuff, but at the end
&lt;/h2&gt;

&lt;p&gt;Then when you have an mvp, you can go wild on the fancy stuff, e.g. machine learning etc. This is a great opportunity to try something new! A great tip would be to not pick up too much and consider the risks of what you're doing (e.g. your skill or knowledge in that field).&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparation is king
&lt;/h2&gt;

&lt;p&gt;One thing that is almost a necessity is to prepare as much as you can. This means: having all the environments working, have all the tools installed and working, have your git repo up &amp;amp; running,... Also consider the things that are not directly needed for development, but are needed for the hackathon: video capturing software, video editing software, communication tools,... Don't underestimate this, because you don't want to browse around the internet for video capturing software 20 minutes before the deadline. I believe also that here a real-life lesson is hidden: a prepared man is worth two.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't spend too much time brainstorming
&lt;/h2&gt;

&lt;p&gt;Although brainstorming and conceptualizing is needed, don't overspend time on this, since you also need to build it. Also when brainstorming take the limited time into account since you won't be able to build everything you want.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stop developing on time
&lt;/h2&gt;

&lt;p&gt;Don't forget that you possibly need to do other stuff than development (depending on the hackathon). So stop on time with the development work so you can capture a demo, write manuals,... because it takes some time to do that stuff. Also remember by that time, you are almost 24h awake so mistakes will be made &amp;amp; your productivity will be lower. Anticipate this by not starting on those tasks the last hour.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;At then end, I can only make one conclusion: Hackathons are a great source of learning! You'll learn about new technologies, software development in general and most importantly yourself!&lt;/p&gt;

</description>
      <category>sitecore</category>
      <category>todayilearned</category>
      <category>learning</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to find the script that changes a html tag's attribute</title>
      <dc:creator>Alex Dhaenens</dc:creator>
      <pubDate>Tue, 03 Mar 2020 13:34:37 +0000</pubDate>
      <link>https://dev.to/alexdhaenens/how-to-find-the-script-that-changes-a-html-attribute-20am</link>
      <guid>https://dev.to/alexdhaenens/how-to-find-the-script-that-changes-a-html-attribute-20am</guid>
      <description>&lt;p&gt;Sometimes you have the luck that you must work on a project that is quite old an contains alot of scripts. Then, one day you are developing (or debugging) and you noticed that a certain html tag's attribute changed. You know that this is done by a script since that attribute does not have that value when viewing the source or when you look at what the backend renders. The next step is then obviously to find that script (and code line) so you can understand why it happens and, if needed fix it.&lt;/p&gt;

&lt;p&gt;The most obvious way to find that script is to set a breakpoint the moment that attribute changed. The thing is, you can't set a breakpoint without knowing the javascript file and line number. &lt;em&gt;Or can you??&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As I found out recently, chrome's dev tools can actually set a breakpoint on the moment an attribute changes.&lt;/p&gt;

&lt;h1&gt;
  
  
  How to do it
&lt;/h1&gt;

&lt;p&gt;To get straight to the point, you can you can right click on a html node and choose &lt;em&gt;break on&lt;/em&gt; and then pick &lt;em&gt;attribute modifications&lt;/em&gt; 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqk3a2d1tje3d79w4ac45.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqk3a2d1tje3d79w4ac45.png" alt="Enabling attribute modifications"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Chrome will add a blue dot left of the html tag:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F60pukvqoq16mw95nl3r1.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F60pukvqoq16mw95nl3r1.png" alt="A breakpoint on an attribute modifications"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, as soon as &lt;strong&gt;an attribute&lt;/strong&gt; changes, the code will stop executing on the line that does the attribute changes&lt;/p&gt;

&lt;h1&gt;
  
  
  Additional tips
&lt;/h1&gt;

&lt;p&gt;Since there are different ways in javascript to change an attribute (E.g. using jQuery, an additional js file,...) you might not end up on the code location you need to be. But on the right side of your dev tools you can see the stack trace. There you can see which function and file called the code you are currently breaking on.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>html</category>
    </item>
    <item>
      <title>How to resize images from the media library with code</title>
      <dc:creator>Alex Dhaenens</dc:creator>
      <pubDate>Fri, 21 Feb 2020 11:30:51 +0000</pubDate>
      <link>https://dev.to/alexdhaenens/how-to-resize-images-from-the-media-library-with-code-36j1</link>
      <guid>https://dev.to/alexdhaenens/how-to-resize-images-from-the-media-library-with-code-36j1</guid>
      <description>&lt;p&gt;One of the missions of a web developer is to make your sites fast &amp;amp; user friendly, something that can be measured by google's speed insights score. One way to do increase your score and speed is to download images in the right size instead of the ( -most of the time- way) bigger size just to then resize it using css. This obviously gives a better speed since you need to download alot less data (which is critical on mobile and low internet devices). In order to download the right size, content editors could upload the correct one to the media library. However this is, due to many reasons (e.g. reusing old images,...), not always possible.&lt;/p&gt;

&lt;p&gt;Luckely for us, Sitecore does have this feature built in. You can resize image from the media library to any size by adding query parameters to the image's url and then adding a protective hash.&lt;/p&gt;

&lt;p&gt;You can do this as follows in vanilla Sitecore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Sitecore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Resources&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Media&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MediaManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetMediaUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mediaItem&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;resizedImageSrc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HashingUtils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ProtectAssetUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;$"?w=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;&amp;amp;h=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For those of you that do use Glassmapper you can do it as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Src&lt;/span&gt;
&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;resizedImageSrc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HashingUtils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ProtectAssetUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;$"?w=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;&amp;amp;h=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Parameters
&lt;/h1&gt;

&lt;p&gt;Besides from setting the width &amp;amp; height you can also set other query parameters:&lt;/p&gt;

&lt;p&gt;° w: Width in pixels&lt;br&gt;
° h: Height in pixels&lt;br&gt;
° mw: Maximum width in pixels&lt;br&gt;
° mh: Maximum height in pixels&lt;br&gt;
° la: Language (defaults to context language)&lt;br&gt;
° vs: Version (defaults to latest version)&lt;br&gt;
° db: Database name (defaults to context database)&lt;br&gt;
° bc: Background color (defaults to black, for white bc=ffffff)&lt;br&gt;
° as: Allow stretch (as=1)&lt;br&gt;
° sc: Scale by floating point number (sc=.25 = 25%)&lt;br&gt;
° thn: Thumbnail (thn=1)&lt;br&gt;
° dmc: Disable media caching, both retrieval and storage (dmc=1)&lt;/p&gt;

&lt;p&gt;which you can just add to the query parameters.&lt;/p&gt;

&lt;h1&gt;
  
  
  Sources
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://community.sitecore.net/technical_blogs/b/sitecorejohn_blog/posts/media-options-and-query-string-parameters-in-the-sitecore-asp-net-cms"&gt;https://community.sitecore.net/technical_blogs/b/sitecorejohn_blog/posts/media-options-and-query-string-parameters-in-the-sitecore-asp-net-cms&lt;/a&gt;&lt;/p&gt;

</description>
      <category>sitecore</category>
      <category>dotnet</category>
      <category>csharp</category>
    </item>
    <item>
      <title>What the hell is property pattern matching?</title>
      <dc:creator>Alex Dhaenens</dc:creator>
      <pubDate>Mon, 10 Feb 2020 11:08:58 +0000</pubDate>
      <link>https://dev.to/alexdhaenens/what-the-hell-is-property-pattern-matching-2008</link>
      <guid>https://dev.to/alexdhaenens/what-the-hell-is-property-pattern-matching-2008</guid>
      <description>&lt;p&gt;I'vealready  made some posts about pattern matching, with the last one about &lt;a href="https://dev.to/alexdhaenens/what-the-hell-is-positional-pattern-matching-9dn-temp-slug-8210505"&gt;positional pattern matching&lt;/a&gt;. Pattern matching made it possible to do a type check, cast to that checked type into a variable and then deconstruct its properties into variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nf"&gt;Elf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;elfishName&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Elf with elfish name&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;elfishName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; years old"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it made it also possible to do a value check while deconstructing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nf"&gt;Elf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;110&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;elfishName&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Elf with elfish name&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;elfishName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is 110 years old"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;One of the drawbacks of this technique is that a deconstructor is needed (more about that in my blogpost about &lt;a href="https://dev.to/alexdhaenens/what-the-hell-is-object-deconstructing-kj0"&gt;object deconstructing&lt;/a&gt;). Luckely for us, &lt;strong&gt;C# 8.0&lt;/strong&gt; provides us with property pattern matching!&lt;/p&gt;

&lt;h1&gt;
  
  
  What is it?
&lt;/h1&gt;

&lt;p&gt;Well property pattern matching does the &lt;strong&gt;same as positional pattern matching&lt;/strong&gt; but &lt;strong&gt;without the need of a _Deconstructor&lt;/strong&gt;_ . The code above, which checks if the &lt;em&gt;person&lt;/em&gt; is an &lt;em&gt;Elf&lt;/em&gt; then deconstructs it and checks if his/her &lt;em&gt;age&lt;/em&gt; is 110, looks like this with property pattern matching:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;Elf&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;110&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ElfishName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;elfishName&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Elf with elfish name&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;elfishName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is 110 years old"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the syntax is quite similar to its counterpart. The downside however, is that it is more (computationally) expensive. &lt;/p&gt;

&lt;h1&gt;
  
  
  Sources
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/deconstruct"&gt;https://docs.microsoft.com/en-us/dotnet/csharp/deconstruct&lt;/a&gt;&lt;br&gt;
Demo project: &lt;a href="https://bitbucket.org/aldhaenens/p-d-demo/src/master/"&gt;https://bitbucket.org/aldhaenens/p-d-demo/src/master/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>What the hell is positional pattern matching?</title>
      <dc:creator>Alex Dhaenens</dc:creator>
      <pubDate>Mon, 03 Feb 2020 11:11:15 +0000</pubDate>
      <link>https://dev.to/alexdhaenens/what-the-hell-is-positional-pattern-matching-46p7</link>
      <guid>https://dev.to/alexdhaenens/what-the-hell-is-positional-pattern-matching-46p7</guid>
      <description>&lt;p&gt;With the arrival of the brand new &lt;strong&gt;C# 8.0&lt;/strong&gt;, a lot of new things are possible! One of my personal favorites is the positional pattern matching feature! &lt;br&gt;
Just like my other posts about C#, I'll be using the &lt;em&gt;Elf&lt;/em&gt; class which has two properties: &lt;em&gt;Age&lt;/em&gt;, which is the age and &lt;em&gt;ElfishName&lt;/em&gt;, which is the name of the elf in elfish. Before we dive into this feature, let me give you a brief refresher of some stuff you need to know in order to understand what is happening.&lt;/p&gt;
&lt;h1&gt;
  
  
  Background
&lt;/h1&gt;

&lt;p&gt;Firsly, as you might know, in C# 7.0 there is a feature called &lt;strong&gt;pattern matching&lt;/strong&gt; (if not you can read about it &lt;a href="https://dev.to/alexdhaenens/what-the-hell-is-pattern-matching-4an8"&gt;here&lt;/a&gt;). Pattern matching makes it possible to do a type check and a cast directly in one line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;Elf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also in c# 7.0 you can extract properties out of an object in one line. This feature is called &lt;strong&gt;object deconstructing&lt;/strong&gt; (you can learn more about this &lt;a href="https://dev.to/alexdhaenens/what-the-hell-is-object-deconstructing-kj0"&gt;here&lt;/a&gt;) and it looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;elfishName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;elf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is a nice feature but, as you might remember, it requires a deconstructor. A deconstructor is a method called &lt;em&gt;Deconstruct&lt;/em&gt; in a class and looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Deconstruct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;elfishName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Age&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;elfishName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ElfishName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  What is it?
&lt;/h1&gt;

&lt;p&gt;In C# 8.0 however, you can &lt;strong&gt;combine both pattern matching &amp;amp; object deconstructing&lt;/strong&gt; which is called &lt;strong&gt;positional pattern matching&lt;/strong&gt;. It is important to note is that just as deconstructing it requires a deconstructor.&lt;/p&gt;

&lt;p&gt;So what does it do? Well, it makes it possible to type check the variable, then cast it to a specific type and then deconstruct it IN ONE LINE! It looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nf"&gt;Elf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;elfishName&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Elf with elfish name&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;elfishName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; years old"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;em&gt;Age&lt;/em&gt; and &lt;em&gt;ElfishName&lt;/em&gt; properties are extracted into the &lt;em&gt;age&lt;/em&gt; and &lt;em&gt;elfishName variables&lt;/em&gt;, just like in object deconstructing. This is a nice shorthand, but don't forget that a deconstructor is required! &lt;/p&gt;

&lt;p&gt;An extra addition is this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;           &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nf"&gt;Elf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;110&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;elfishName&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Elf with elfish name&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;elfishName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is 110 years old"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this piece of code, I've already provided a const value (in this case 110) against which the casted object is checked. So what this one line actually does, is firstly it checks if the person is an &lt;em&gt;Elf&lt;/em&gt;, casts it, then deconstructs the casted object and lastly checks if the &lt;em&gt;Age&lt;/em&gt; property is equal to 110. You can then access the &lt;em&gt;ElfishName&lt;/em&gt; of that casted object in the &lt;em&gt;elfishName&lt;/em&gt; variable. Isn't this nice??&lt;/p&gt;

&lt;h1&gt;
  
  
  Source
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#positional-patterns"&gt;https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#positional-patterns&lt;/a&gt;&lt;br&gt;
Demo project: &lt;a href="https://bitbucket.org/aldhaenens/p-d-demo/src/master/"&gt;https://bitbucket.org/aldhaenens/p-d-demo/src/master/&lt;/a&gt;&lt;/p&gt;

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