<?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: Amerigo Mancino</title>
    <description>The latest articles on DEV Community by Amerigo Mancino (@amerigom).</description>
    <link>https://dev.to/amerigom</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%2F522184%2F8c5df75e-93e3-4635-9843-2b9862b488cd.jpeg</url>
      <title>DEV Community: Amerigo Mancino</title>
      <link>https://dev.to/amerigom</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/amerigom"/>
    <language>en</language>
    <item>
      <title>How to create a debouncing timer in Swift</title>
      <dc:creator>Amerigo Mancino</dc:creator>
      <pubDate>Thu, 05 May 2022 11:14:16 +0000</pubDate>
      <link>https://dev.to/amerigom/how-to-create-a-debouncing-timer-in-swift-5ff6</link>
      <guid>https://dev.to/amerigom/how-to-create-a-debouncing-timer-in-swift-5ff6</guid>
      <description>&lt;p&gt;One common problem people tends to underestimate is when users decide to stress a heavy functionality within your app, for example by pressing a button numerous times in a small span, resulting in crashes and undefined behaviors.&lt;/p&gt;

&lt;p&gt;One way to overcome this problem is to create a &lt;em&gt;debouncing timer&lt;/em&gt;. We do that by defining a couple of variables inside the class where the functionality is used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private var debouncingTimer: Timer? = nil
private let DEBOUNCE_TIME: TimeInterval = 0.5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The debounce time is the minimum interval for the heavy code to occur. Within that time span other user interactions will be ignored.&lt;/p&gt;

&lt;p&gt;Then, from within the outlet of the button who triggers your heavy functionality we perform the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if debouncingTimer == nil || debouncingTimer?.isValid == false {
    self.debouncingTimer = Timer.scheduledTimer(
        withTimeInterval: DEBOUNCE_TIME,
        repeats: false) { [weak self] timer in
                timer.invalidate()
                self?.debouncingTimer = nil
            }

    // your heavy functionality
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By doing this, we set a timer every time the heavy code is triggered and we protect it until the timer keeps running.&lt;/p&gt;

&lt;p&gt;When the timer is invalidated, the functionality becomes available for the user again.&lt;/p&gt;

</description>
      <category>swift</category>
      <category>ios</category>
    </item>
    <item>
      <title>A real CarPlay Simulator: take off guide</title>
      <dc:creator>Amerigo Mancino</dc:creator>
      <pubDate>Wed, 02 Feb 2022 11:40:06 +0000</pubDate>
      <link>https://dev.to/amerigom/a-real-carplay-simulator-take-off-guide-3557</link>
      <guid>https://dev.to/amerigom/a-real-carplay-simulator-take-off-guide-3557</guid>
      <description>&lt;p&gt;Working with CarPlay might be though for various reasons and the recent upgrade to M1 chips only added more problems to the matter. Having to integrate third party libraries within your project that are not build for M1, having to run Xcode on Rosetta and having to support CarPlay is a difficult challenge for every developer nowadays.&lt;/p&gt;

&lt;p&gt;Luckily Apple has recently released a standalone CarPlay simulator as a separate app that can natively run on your Mac. Let's see how to set it up and how it works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Download and Install
&lt;/h2&gt;

&lt;p&gt;At the time of writing, the only way to download the app is through the &lt;a href="https://developer.apple.com/download/all/?q=xcode"&gt;Apple Developer Portal&lt;/a&gt;. Download the &lt;em&gt;Additional Tools for Xcode 13.2&lt;/em&gt;, then open the image file and go under the &lt;em&gt;Hardware&lt;/em&gt; folder. Move the &lt;em&gt;CarPlay simulator&lt;/em&gt; app to your Application directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;p&gt;There is no official guide on how to configure your iPhone to be ready for the simulator. The only thing you have to make sure of is to turn off your hotspot on your device (if on). When this step is done, connect your device to your Mac and open the simulator. On your iPhone you should see a message from the simulator requiring permissions. Grant them and it will load the CarPlay interface. On the simulator menu, under &lt;em&gt;Devices&lt;/em&gt;, you should see your device name with a green icon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;

&lt;p&gt;You can use this simulator for development purposes. When you run an app on debug mode and open the app on the simulator, all your print statements and breakpoints will be triggered.&lt;/p&gt;

</description>
      <category>carplay</category>
      <category>ios</category>
      <category>xcode</category>
      <category>swift</category>
    </item>
    <item>
      <title>How to create a custom Angular async validator</title>
      <dc:creator>Amerigo Mancino</dc:creator>
      <pubDate>Thu, 04 Feb 2021 12:03:43 +0000</pubDate>
      <link>https://dev.to/amerigom/how-to-create-a-custom-angular-async-validator-4dd6</link>
      <guid>https://dev.to/amerigom/how-to-create-a-custom-angular-async-validator-4dd6</guid>
      <description>&lt;p&gt;Angular provides a certain number of ways to validate your input data. With attributes like &lt;code&gt;required&lt;/code&gt; or &lt;code&gt;maxlength&lt;/code&gt; we can easily control what a user can and cannot insert in a form.&lt;/p&gt;

&lt;p&gt;However, what if the validation has to happen on the backend? How do I implement a custom validator that is able to call a backend service and return the validation result?&lt;/p&gt;

&lt;p&gt;In this article, I will guide you through the steps you need to perform in order to create your custom asynchronous validator.&lt;/p&gt;

&lt;h2&gt;
  
  
  The backend service
&lt;/h2&gt;

&lt;p&gt;For the purpose of this example, let's imagine we have an endpoint which accepts, in the request body, a structure like the following one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
   "objectType": "SOME_OBJECT_TYPE",
   "value": "Some name"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where &lt;code&gt;value&lt;/code&gt; is the value to validate and &lt;code&gt;objectType&lt;/code&gt; contains some information needed by the sever.&lt;/p&gt;

&lt;p&gt;To this call, the server responds with another object containing the field &lt;code&gt;valid&lt;/code&gt; (the validation result) and a message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
   "valid": false,
   "message": "Must not be blank"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The validator
&lt;/h2&gt;

&lt;p&gt;To create a custom validator, we need to create a new directive by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng generate directive nameIsValid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's define the directive decorator first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Directive({
  selector: '[nameIsValid][ngModel],[nameIsValid][FormControl]',
    providers: [
        {
            provide: NG_ASYNC_VALIDATORS,
            useExisting: NameIsValidDirective, 
            multi: true
        }
    ]
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above registers the validator, so Angular is aware it exists and can use it during binding. This means that thereafter we can use it in an input field as in the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input
  type="text"
  id="name"
  name="name"
  nameIsValid
&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Moving back to the directive, we can now populate the validator class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class NameIsValidDirective implements AsyncValidator {

  private validationServiceUrl = "my backend url";

  constructor(
    private http: HttpClient
  ) { }

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

&lt;/div&gt;



&lt;p&gt;As you can see, the &lt;code&gt;NameIsValidDirective&lt;/code&gt; class implements the &lt;code&gt;AsyncValidator&lt;/code&gt; interface which requires us to define a &lt;code&gt;validate&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;validate(control: AbstractControl): 
   Observable&amp;lt;ValidationErrors | null&amp;gt; {

    let fieldToValidate = {
        objectType: "NAME_VALUE",
        value: control.value
    };

    const request = this.validationServiceUrl

    const obs = this.http.post&amp;lt;any&amp;gt;(request, fieldToValidate)
        .pipe(
            map((validationResult) =&amp;gt; {
                // null no error, object for error
                return validationResult.valid === true ? null : {
                  NameIsValidDirective : validationResult.message
                };
            })
        );
    return obs;
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;control.value&lt;/code&gt; contains the value the user inserted in the input field. With this information, we build the object to send to the backend, make a call and get the response: if the validation went good, we must return &lt;code&gt;null&lt;/code&gt;, otherwise we must return an object. In this example, I chose to return the validation error message.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Despite typically there is no need to create custom validators at all, there are specific cases or architectural needs where we require to perform a validation on the backend side. When this case occurs, you are now aware of how custom validators work and you successfully learned how to implement one.&lt;/p&gt;

</description>
      <category>angular</category>
    </item>
    <item>
      <title>Scrum for dummies</title>
      <dc:creator>Amerigo Mancino</dc:creator>
      <pubDate>Sun, 06 Dec 2020 17:30:46 +0000</pubDate>
      <link>https://dev.to/amerigom/scrum-for-dummies-23k1</link>
      <guid>https://dev.to/amerigom/scrum-for-dummies-23k1</guid>
      <description>&lt;h1&gt;
  
  
  Agile methodology
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Agile methodology&lt;/strong&gt; refers to a set of software development methods that are opposed to the Waterfall Model and other traditional approaches. It proposes a less structured approach that focuses on the objective of delivering to the customer - frequently and in a short time - working and quality software.&lt;/p&gt;

&lt;p&gt;Among the practices promoted by agile methods are the formation of small, self-organised development teams, adaptive planning and the direct and continuous involvement of the client in the development process.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://agilemanifesto.org/"&gt;Agile Manifesto&lt;/a&gt; is based on four principals:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Individuals and interactions over processes and tools.&lt;/li&gt;
&lt;li&gt;Working software over comprehensive documentation.&lt;/li&gt;
&lt;li&gt;Customer collaboration over contract negotiation.&lt;/li&gt;
&lt;li&gt;Responding to change over following a plan.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Waterfall Model
&lt;/h1&gt;

&lt;p&gt;The &lt;strong&gt;Waterfall Model&lt;/strong&gt; is the most traditional model describing the software life-cycle. According to it, the software development process is structured into the following five clear phases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Requirements analysis&lt;/li&gt;
&lt;li&gt;Design&lt;/li&gt;
&lt;li&gt;Development&lt;/li&gt;
&lt;li&gt;Test&lt;/li&gt;
&lt;li&gt;Maintenance&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;As we can see, the most important distinction among the two models is the fact that Agile provides a development for subsequent refinements which the Waterfall Model does not.&lt;/p&gt;

&lt;h1&gt;
  
  
  Scrum
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Definitions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Scrum&lt;/strong&gt; is an Agile Framework. You can think of it as one possible implementation of the Agile guidelines: if Agile provides the recipe, Scrum puts in the ingredients to realize it.&lt;/p&gt;

&lt;p&gt;To create a &lt;strong&gt;product&lt;/strong&gt; with Scrum, we receive specifics from &lt;strong&gt;stakeholders&lt;/strong&gt;, i.e. from all those interested in creating the product itself.&lt;/p&gt;

&lt;p&gt;In Scrum those specifics are called &lt;strong&gt;user stories&lt;/strong&gt; or just &lt;strong&gt;stories&lt;/strong&gt; and they are a brief description of a requested feature under the user's point of view. The way user stories are written is overall standard:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;As a &amp;lt;type of user&amp;gt;
I want &amp;lt;some goal&amp;gt;
So that &amp;lt;some reasons&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All the stories are grouped into the &lt;strong&gt;product backlog&lt;/strong&gt; which is a required list of features related to the product.&lt;/p&gt;

&lt;p&gt;In Scrum people necessary for the realization of a product are divided into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Product Owner&lt;/strong&gt; - represents the stackeholders and is the voice of the clients. He ensures that the product developed provides value to the business and writes the stories assigning them a priority. Then he adds them to the Backlog.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scrum Master&lt;/strong&gt; - removes obstacles that limit the team's ability to achieve the sprint goal. He is &lt;em&gt;not&lt;/em&gt; the Team Leader&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Development Team&lt;/strong&gt; - they are responsible for product development; generally consisting of 3 to 9 people, it self-organises and self-manages.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A &lt;strong&gt;Sprint&lt;/strong&gt; is the base development unit of Scrum development. With a fixed duration (from 1 to 4 weeks), during the Sprint the team works and develops all the user stories that pledged to deliver at the end of the Sprint. The delivered product at the end of each Sprint is called &lt;strong&gt;increment&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Workflow
&lt;/h3&gt;

&lt;p&gt;The most common events that occur during a Scrum process are the followings:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Backlog refinement&lt;/strong&gt; - The Product Owner meets the team to discuss the stories currently in Backlog. He shares the priority of each story and defines the concept of &lt;em&gt;done&lt;/em&gt;, i.e. when a story can be considered as finished.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sprint Planning&lt;/strong&gt; - The team chooses the stories it undertakes to deliver at the end of the Sprint. This choice is made considering the priorities assigned by the Product Owner.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sprint&lt;/strong&gt; - As already discussed above, during a Sprint the team works to develop the user stories assigned to the Sprint. At the end of each Sprint, the value of the stories (generally measured in &lt;strong&gt;story points&lt;/strong&gt;) contributes to give an estimation of the speed's team. A certain number of story points corresponds to a certain amount of hours that the team expects to need to finish the story.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Daily Scrum&lt;/strong&gt; - The Scrum Master meets the team and each member answers to three simple questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What have I done yesterday?&lt;/li&gt;
&lt;li&gt;What am I going to do today?&lt;/li&gt;
&lt;li&gt;What are the obstacles I encountered yesterday during my work?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sprint Review&lt;/strong&gt; - The team shows to the Product Owner and the Stakeholders what he did during the Sprint. Generally, this meeting includes a demo of the new functionalities implemented in the application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sprint Retrospective&lt;/strong&gt; - The Scrum Master meets the team and tries to identify the things the team does well, what it should start doing to improve performance and what it should stop doing.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The following diagram describes in which order these events occur:&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Implement Scrum
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.atlassian.com/software/jira"&gt;Jira&lt;/a&gt; is a professional and complete tool implementing Scrum. It's often used by large companies and offers a &lt;strong&gt;board&lt;/strong&gt; where all the stories for a given Sprint are presented.&lt;/p&gt;

&lt;p&gt;Stories on the board are sometimes called &lt;strong&gt;tickets&lt;/strong&gt;. Jira includes a distinction among tickets to simplify the planning part. They are divided into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Epics&lt;/strong&gt; - Very big tickets that generally contain a general use case that is a collection of user stories (i.e. authentication).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User stories&lt;/strong&gt; - Represents a user feature (i.e. forgot password).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sub tasks&lt;/strong&gt; - Development tasks to accomplish a user story (i.e. implement HTML/CSS of login screen).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Defects&lt;/strong&gt; - A bug was found in a released story and needs to be fixed (i.e. login button doesn't work on Safari).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A less popular and less professional tool to implement Scrum is &lt;a href="https://trello.com/"&gt;Trello&lt;/a&gt;. It is very simple to use and - despite having less features than Jira - it is recommended for projects that don't require a strong management infrastructure for building, fixing and releasing software. It is also definitely a good starting point for learning how Agile development works.&lt;/p&gt;

&lt;p&gt;Trello provides a &lt;a href="https://trello.com/b/VliA4Xzm/scrum"&gt;public board&lt;/a&gt; where you can learn more about Scrum and using the tool.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why does Scrum fail?
&lt;/h1&gt;

&lt;p&gt;What we learned so far is that Scrum is great and provides a useful support in planning, organization and development. Then &lt;em&gt;why does it (sometimes) fail?&lt;/em&gt; or rather, to be more precise, &lt;em&gt;why Scrum fails in large enterprises?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There are various reasons behind that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Product Owner is not involved in the process as much as he should and doesn't have a customer mindset.&lt;/li&gt;
&lt;li&gt;Team members lack in experience (and consequently fail a Sprint).&lt;/li&gt;
&lt;li&gt;The Scrum Master fails in removing the obstacles encountered by the team.&lt;/li&gt;
&lt;li&gt;No clear roles distinction.&lt;/li&gt;
&lt;li&gt;Bureaucracy prevents a successful Sprint (i.e. tickets are blocked because they are not approved).&lt;/li&gt;
&lt;li&gt;Bad management and pyramidal scheme.&lt;/li&gt;
&lt;li&gt;The team is not informed on the &lt;em&gt;big picture&lt;/em&gt; and completes user stories blindly.&lt;/li&gt;
&lt;li&gt;Lack of testing strategies.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can reconnect most of these problems I mentioned (and those I didn't mention you can add to the list) to a main one: &lt;em&gt;lack of communication&lt;/em&gt;. Meetings and discussions are important but they need to provide additional value to the entities joining in: the team must have a clear vision of what they are building, the Product Owner shouldn't start doing commands or speak one-to-one with developers, the Scrum Master must fulfill his role of "man in the middle".&lt;/p&gt;

&lt;p&gt;Unfortunately large companies have always difficulties in integrating Agile in their structure and/or they do not have sufficient experience in understanding how to do it properly: they have different business units, more processes and, most important, a strong culture that defines how things are done, and this is something that makes an integration even more difficult.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusions
&lt;/h1&gt;

&lt;p&gt;Agile methodology and Scrum offer useful mindsets and tools to deal with development for subsequent refinements and in turn propose a successful working strategy. Unfortunately, large companies often fail in implementing it due to their culture and their complexity. However, by putting effort in integrating it, Agile proves to be a reliable method for software developing.&lt;/p&gt;

</description>
      <category>agile</category>
    </item>
    <item>
      <title>How to ActivatedRoute in Angular and how to mock it in Unit Tests</title>
      <dc:creator>Amerigo Mancino</dc:creator>
      <pubDate>Wed, 02 Dec 2020 09:24:02 +0000</pubDate>
      <link>https://dev.to/amerigom/how-to-activatedroute-in-angular-and-how-to-mock-it-in-unit-tests-2ne6</link>
      <guid>https://dev.to/amerigom/how-to-activatedroute-in-angular-and-how-to-mock-it-in-unit-tests-2ne6</guid>
      <description>&lt;p&gt;The topic of testing is always mistreated online. It's easy to check that on a hundred articles explaining how to develop a certain functionality, only one or two include a description of how to test it. Even in large projects and in big companies, it is not rare to just forget about testing because time is short or because workarounds are possible. This is a terrible behavior: the bigger the project, the easier it becomes to break something while implementing something else and - without unit tests - there is no way to know it for sure.&lt;/p&gt;

&lt;p&gt;In this tutorial, I will explain you how to use &lt;code&gt;ActivatedRoute&lt;/code&gt; to pass a parameter from a component to another and how to mock it in the corresponding Unit Test.&lt;/p&gt;

&lt;h1&gt;
  
  
  How to pass a parameter with ActivatedRoute
&lt;/h1&gt;

&lt;p&gt;Let's say we have a Home component where we display a list of users. Our goal is to pass the user &lt;code&gt;id&lt;/code&gt; via the web url, retrieve it and use it in a User component to collect - for example - all the user details:&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%2F3ew2qi7dwhfnfh9kemsh.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%2F3ew2qi7dwhfnfh9kemsh.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To achieve that, first we need to define the route in &lt;code&gt;app-routing.module.ts&lt;/code&gt; as the following:&lt;/p&gt;

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

{
  path: 'user/:id',
  component: UserComponent
},


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

&lt;/div&gt;

&lt;p&gt;To pass the id we have two possibilities:&lt;/p&gt;

&lt;p&gt;The first one is by editing the HTML in the Home component:&lt;/p&gt;

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

&amp;lt;a [routerLink]="['user', id]"&amp;gt;
   &amp;lt;!-- When clicked I redirect to the User component --&amp;gt;
&amp;lt;/a&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;The alternative is to navigate inside a typescript function; import the &lt;code&gt;Router&lt;/code&gt; and declare it in the constructor:&lt;/p&gt;

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

constructor(
  private router: Router
) { }


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

&lt;/div&gt;

&lt;p&gt;Then use it in your function:&lt;/p&gt;

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

this.router.navigate(['/user', id]);


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

&lt;/div&gt;

&lt;p&gt;In the User component we can at last retrieve the id.&lt;br&gt;
Let's import the &lt;code&gt;ActivatedRoute&lt;/code&gt; and declare it in the constructor:&lt;/p&gt;

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

constructor(
  private activatedRoute: ActivatedRoute,
) { }


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

&lt;/div&gt;

&lt;p&gt;Afterwards in the &lt;code&gt;ngOnInit()&lt;/code&gt; we can get the id:&lt;/p&gt;

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

const id = this.activatedRoute.snapshot.params.id;


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

&lt;/div&gt;

&lt;p&gt;Once we have it, we can use it the way we like. For example, we can pass it as a parameter to a service and retrieve the User details as stated above.&lt;/p&gt;

&lt;h1&gt;
  
  
  Unit test
&lt;/h1&gt;

&lt;p&gt;It is pretty straightforward to mock the &lt;code&gt;ActivatedRoute&lt;/code&gt; in the User component test file. All we have to do is to edit the &lt;code&gt;providers&lt;/code&gt; list as follows:&lt;/p&gt;

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

beforeEach(async(() =&amp;gt; {
    TestBed.configureTestingModule({
      declarations: [ UserComponent ],
      imports: [
        RouterTestingModule,
        HttpClientTestingModule
        // ... whatever other module you have
      ],
      providers:
      [
        {
          provide: ActivatedRoute,
          useValue: {
            snapshot: {params: {id: '24fkzrw3487943uf358lovd'}}
          }
        }
      ]
    })
    .compileComponents();
}));


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

&lt;/div&gt;

&lt;p&gt;That's it!&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;npm test&lt;/code&gt; in a terminal to execute all your unit tests and check the outcome!&lt;/p&gt;

</description>
      <category>angular</category>
      <category>testing</category>
    </item>
    <item>
      <title>How to dockerize an Angular app for different environments</title>
      <dc:creator>Amerigo Mancino</dc:creator>
      <pubDate>Mon, 30 Nov 2020 16:16:15 +0000</pubDate>
      <link>https://dev.to/amerigom/how-to-dockerize-an-angular-app-for-different-environments-1njb</link>
      <guid>https://dev.to/amerigom/how-to-dockerize-an-angular-app-for-different-environments-1njb</guid>
      <description>&lt;p&gt;Docker is an open-source tool designed to help programmers in development and deployment. It makes use of a structure called "container" which wraps the application and its dependencies together so that it can be executed on any machine. This is particularly important when have to deal with different servers - testing, integration, production - where the applications must run without any error or compatibility issue.&lt;/p&gt;

&lt;p&gt;In this tutorial I will explain how to dockerize an Angular application for different target environments.&lt;/p&gt;

&lt;h1&gt;
  
  
  Set up custom environments in Angular
&lt;/h1&gt;

&lt;p&gt;By default, Angular provides two different environment files, that can be found in the &lt;code&gt;environments&lt;/code&gt; folder:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foeqkvmlmyepqsu26wlrw.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%2Foeqkvmlmyepqsu26wlrw.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's add a couple more! Create two new files named &lt;code&gt;environment.test.ts&lt;/code&gt; and &lt;code&gt;environment.int.ts&lt;/code&gt; and replace in there your urls with the ones you want to use for the target environment. Here is my &lt;code&gt;environment.int.ts&lt;/code&gt;:&lt;/p&gt;

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

export const environment = {
    production: false,
    name: 'int',
    functionUrls: {
        data1: 'my-data1-int-url',
        data2: 'my-data2-int-url'
    }
};


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

&lt;/div&gt;

&lt;p&gt;Then we need to tell Angular that we have new build configurations: edit the &lt;code&gt;angular.json&lt;/code&gt; file and create new entries under &lt;code&gt;architect → build → configuration&lt;/code&gt;. As you can see, the production and local (serve) entries are already present.&lt;/p&gt;

&lt;p&gt;When inserting a custom environment we only need to notify the framework to replace the default &lt;code&gt;environment.ts&lt;/code&gt; with the one we want at build-time, so in principle it is sufficient to add the following:&lt;/p&gt;

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

"int": {
  "fileReplacements": [
     {
      "replace": "src/environments/environment.ts",
      "with": "src/environments/environment.int.ts"
     }
  ],
},


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

&lt;/div&gt;

&lt;p&gt;We can customize the build options by adding extra settings. Refer to the &lt;a href="https://angular.io/guide/build" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt; for further details.&lt;/p&gt;

&lt;p&gt;As a last step, let's edit the &lt;code&gt;package.json&lt;/code&gt; and write some commands to build the app more easily:&lt;/p&gt;

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

"scripts": {
   "ng": "ng",
   "start": "ng serve",
   "build": "ng build",
   "build-test": "ng build --configuration=test",
   "build-int": "ng build --configuration=int",
   "build-prod": "ng build --prod",
   "test": "ng test",
   "lint": "ng lint",
   "e2e": "ng e2e"
},


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

&lt;/div&gt;

&lt;p&gt;Let's build our app!&lt;/p&gt;

&lt;p&gt;Open a terminal and from the main project folder run &lt;code&gt;npm build-int&lt;/code&gt;. This will build the application for the int environment. Your output is located into the &lt;code&gt;dist&lt;/code&gt; folder in your project, ready to be deployed on a server.&lt;/p&gt;

&lt;p&gt;If you want, you can test it using &lt;code&gt;http-server&lt;/code&gt;. Install it with:&lt;/p&gt;

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

npm install http-server -g


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

&lt;/div&gt;

&lt;p&gt;Run it with:&lt;/p&gt;

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

http-server ./dist


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

&lt;/div&gt;

&lt;p&gt;It will start serving your project from the &lt;code&gt;dist&lt;/code&gt; folder.&lt;/p&gt;

&lt;h1&gt;
  
  
  Integrate Docker
&lt;/h1&gt;

&lt;p&gt;Now that we can build a project for different environments, it's time to integrate Docker and run the application in a container. First, create a &lt;code&gt;docker&lt;/code&gt; folder inside the project, which will contain all the docker-related files. Then create a &lt;code&gt;docker-compose&lt;/code&gt; file for each environment: &lt;code&gt;docker-compose.int.yml&lt;/code&gt; for integration , &lt;code&gt;docker-compose.test.yml&lt;/code&gt; for testing and so on. These files look like the following:&lt;/p&gt;

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

version: '3.3'

services:
  myapp:
    image: myapp
    build:
      context: ../
      dockerfile: docker/Dockerfile
      args:
        PROFILE: int
    ports:
      - "8080:80"


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

&lt;/div&gt;

&lt;p&gt;What's important to notice here is the line&lt;/p&gt;

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

PROFILE: int


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

&lt;/div&gt;

&lt;p&gt;were we define the environment we want to use: we'll inject this variable in the &lt;code&gt;Dockerfile&lt;/code&gt; in a moment.&lt;/p&gt;

&lt;p&gt;Let's create the &lt;code&gt;Dockerfile&lt;/code&gt;:&lt;/p&gt;

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

FROM node:12.16.1-alpine As builder

### STAGE 1: Build ###
WORKDIR /usr/src/app
COPY package.json package-lock.json ./

RUN npm install

COPY . .

ARG PROFILE
ENV PROFILE $PROFILE

RUN echo "Environment: ${PROFILE}"
RUN npm run build-${PROFILE}

### STAGE 2: Run ###
FROM nginx:1.15.8-alpine

COPY --from=builder /usr/src/app/dist/myapp/ /usr/share/nginx/html
COPY --from=builder /usr/src/app/docker/nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80


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

&lt;/div&gt;

&lt;p&gt;In stage one we build the application and restore the &lt;code&gt;node_modules&lt;/code&gt;. As you can see, we use the &lt;code&gt;PROFILE&lt;/code&gt; variable we defined above to retrieve the correct environment.&lt;/p&gt;

&lt;p&gt;In stage two we run the application using nginx, which is an http and reverse proxy server. By default, nginx http server listens for incoming connection on port 80, which represents the standard web port. In the &lt;code&gt;docker-compose&lt;/code&gt; we match that port with 8080.&lt;/p&gt;

&lt;p&gt;In addition, note that here&lt;/p&gt;

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

COPY --from=builder /usr/src/app/docker/nginx.conf /etc/nginx/conf.d/default.conf


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

&lt;/div&gt;

&lt;p&gt;we replace the default nginx configuration with ours. To do so, we need to create one last file in our &lt;code&gt;docker&lt;/code&gt; folder, called &lt;code&gt;nginx.conf&lt;/code&gt;:&lt;/p&gt;

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

server {
  listen 80;
  location / {
    root /usr/share/nginx/html;
    index index.html index.htm;
    try_files $uri $uri/ /index.html =404;
  }
}


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

&lt;/div&gt;

&lt;p&gt;All games are done! Let's try to make this work.&lt;/p&gt;

&lt;p&gt;If we want to build and run the configuration for integration, we only need to run the following commands in a terminal:&lt;/p&gt;

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

docker-compose -f docker/docker-compose-int.yml build
docker-compose -f docker/docker-compose-int.yml up


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

&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;up&lt;/code&gt; command will append the console at a message saying &lt;code&gt;Attaching to...&lt;/code&gt;, then it goes to print logs.&lt;br&gt;
Navigate to &lt;code&gt;localhost:8080&lt;/code&gt; to check the outcome.&lt;/p&gt;

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