<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Code D' Ivoire</title>
    <description>The latest articles on Forem by Code D' Ivoire (@codedivoire).</description>
    <link>https://forem.com/codedivoire</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%2Forganization%2Fprofile_image%2F799%2F6f5fc28b-1128-4ea5-9e6f-77ef6232eb10.jpg</url>
      <title>Forem: Code D' Ivoire</title>
      <link>https://forem.com/codedivoire</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/codedivoire"/>
    <language>en</language>
    <item>
      <title>How to mock an imported Typescript class with Jest</title>
      <dc:creator>Abou Kone</dc:creator>
      <pubDate>Thu, 02 Apr 2020 23:52:31 +0000</pubDate>
      <link>https://forem.com/codedivoire/how-to-mock-an-imported-typescript-class-with-jest-2g7j</link>
      <guid>https://forem.com/codedivoire/how-to-mock-an-imported-typescript-class-with-jest-2g7j</guid>
      <description>&lt;p&gt;Sooner or later in your unit tests you will run into an issue where you need to import a class into your test and mock it, to keep up with good test hygiene. Jest offers a pretty good &lt;a href="https://jestjs.io/docs/en/es6-class-mocks#spying-on-the-constructor" rel="noopener noreferrer"&gt;how to in their documentation&lt;/a&gt; on how to set it up for ES6 classes but if you try those instructions out of the box with Typescript, you will run into the type monster. This is a quick post to get it working for Typescript if you're using Jest. If you're an Angular developer and have not set up Jest yet, &lt;a href="https://www.amadousall.com/how-to-set-up-angular-unit-testing-with-jest/" rel="noopener noreferrer"&gt;follow this great tutorial&lt;/a&gt; by Amadou Sall, the bonus is that you will also set up &lt;code&gt;jest-preset-angular&lt;/code&gt;, which will help down the road.&lt;/p&gt;

&lt;h3&gt;
  
  
  SoundPlayer Class
&lt;/h3&gt;

&lt;p&gt;Let's say this is your &lt;code&gt;sound-player.ts&lt;/code&gt; file:&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 SoundPlayer {
  constructor() {
    this.foo = 'bar';
  }

  playSoundFile(fileName) {
    console.log('Playing sound file ' + fileName);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that this is not a default export. That's an important factor that if you follow the Jest documentation, their examples assumes that you're using default exports, which will matter later on in the mock.&lt;/p&gt;

&lt;h3&gt;
  
  
  SoundPlayer Mock
&lt;/h3&gt;

&lt;p&gt;Now let's say you're writing a unit test for another class, let's say &lt;code&gt;SoundPlayerConsumer&lt;/code&gt; and you want to mock SoundPlayer. If you don't have &lt;a href="https://github.com/kulshekhar/ts-jest" rel="noopener noreferrer"&gt;ts-jest&lt;/a&gt; installed, I highly recommend to add it to your Jest configuration now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add --dev ts-jest @types/jest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Like I mentioned earlier, if you're using &lt;a href="https://github.com/thymikee/jest-preset-angular" rel="noopener noreferrer"&gt;jest-preset-angular&lt;/a&gt;, it already comes "bundled" with ts-jest.&lt;/p&gt;

&lt;p&gt;With ts-jest in the bag, mocking a Typescript class with Jest is as easy as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { mocked } from 'ts-jest/utils';
import { SoundPlayer } from './sound-player';

jest.mock('./sound-player', () =&amp;gt; {
  return {
    SoundPlayer: jest.fn().mockImplementation(() =&amp;gt; {
      return {
        playSoundFile: () =&amp;gt; {},
      };
    })
  };
});

describe('SoundPlayerConsumer', () =&amp;gt; {
  const MockedSoundPlayer = mocked(SoundPlayer, true);

  beforeEach(() =&amp;gt; {
   // Clears the record of calls to the mock constructor function and its methods
   MockedSoundPlayer.mockClear();

  });

  it('We can check if the consumer called the class constructor', () =&amp;gt; {
    const soundPlayerConsumer = new SoundPlayerConsumer();
    expect(MockedSoundPlayer).toHaveBeenCalledTimes(1);
  });

}

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

&lt;/div&gt;



&lt;p&gt;It's pretty self explanatory but here are some clarification points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Contrarily to the Jest documentation, since we're not using a default export, we have to reflect the namespace of the exported class module:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return {
    SoundPlayer: jest.fn().mockImplementation(() =&amp;gt; {
      return {
        playSoundFile: () =&amp;gt; {},
      };
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this was a default module, we could have written it simply as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  return jest.fn().mockImplementation(() =&amp;gt; {
    return {playSoundFile: mockPlaySoundFile};
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're getting a “TypeError: ”X“.default is not a constructor.” when trying to run your tests, it's because you have not reflected the exported namespace properly.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; The magic here happens because of the &lt;a href="https://github.com/kulshekhar/ts-jest/blob/master/docs/user/test-helpers.md" rel="noopener noreferrer"&gt;mocked&lt;/a&gt; method, which according to the documentation :&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;The mocked test helper provides typings on your mocked modules and even their deep methods, based on the typing of its source. It make use of the latest TypeScript features so you even have argument types completion in the IDE (as opposed to jest.MockInstance).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The first tell tale sign that your setup is not right would be getting an error of type &lt;code&gt;error TS2339: Property 'mockClear' does not exist on type X&lt;/code&gt; X being the class you are trying to mock.&lt;/p&gt;

&lt;p&gt;I hope this helps you write better unit tests.&lt;/p&gt;

</description>
      <category>jest</category>
      <category>testing</category>
      <category>angular</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Angular Testability: Dealing with Selenium or Protractor timeouts</title>
      <dc:creator>Abou Kone</dc:creator>
      <pubDate>Wed, 01 Apr 2020 21:40:24 +0000</pubDate>
      <link>https://forem.com/codedivoire/angular-testability-dealing-with-selenium-or-protractor-timeouts-479f</link>
      <guid>https://forem.com/codedivoire/angular-testability-dealing-with-selenium-or-protractor-timeouts-479f</guid>
      <description>&lt;p&gt;Running automated integration tests is a crucial element for any serious CI/CD pipeline and within our company, our QA uses Selenium for that purpose. Angular offers Protractor for that purpose, but to each artisan his tool, our Angular apps are just part of a suite that include non Angular apps and it's easier for the team to test them all using Selenium. &lt;/p&gt;

&lt;p&gt;Anybody that has messed with Protractor knows that one of the early frustrations you will run into is knowing from the Selenium's perspective when the Angular page is done doing what it does and is ready to be tested. For novices that would mean any API calls you would be making to the backend to get data, any animation running on the page that as a user you typically wait for before knowing that yes, this page looks like it's ready for me to interact with. Early on our team ran into just that issue and time and resources being an issue, decided to use timers to wait for a reasonable time for the test to assume that the page is ready to interact with. That works most of the time but of course it's not the way you want to run a long term stable QA solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Testability API
&lt;/h2&gt;

&lt;p&gt;For the purpose of testability, Angular exposes the &lt;a href="https://angular.io/api/core/Testability" rel="noopener noreferrer"&gt;Testability API&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Testability service provides testing hooks that can be accessed from the browser and by services such as Protractor. Each bootstrapped Angular application on the page will have an instance of Testability. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Plugging into that API is the way for your testing framework to know when your Angular app is ready to be tested. It uses &lt;a href="https://angular.io/api/core/NgZone" rel="noopener noreferrer"&gt;NgZone&lt;/a&gt; to keep track of all outstanding operations currently running in your application and once they are all completed, marks your application as stable. The way that is done with most selenium scripts is to run a Javascript script from within Selenium that does one of the following:&lt;/p&gt;

&lt;p&gt;Synchronously you can execute a Wait condition that waits for your script to return true like:&lt;br&gt;
&lt;/p&gt;

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

 wait.until(new ExpectedCondition&amp;lt;Boolean&amp;gt;() {
            public Boolean apply(WebDriver driver) {
                String angularScriptPath = "src/angular-script.js";
                String angularScript = null;
                try {
                    angularScript = SeleniumWebDriverTest.readFile(angularScriptPath);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                Boolean angularPageLoaded = ((JavascriptExecutor) driver).executeScript(angularScript);

                return angularPageLoaded;
            }
        });

...


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

&lt;/div&gt;



&lt;p&gt;and your &lt;code&gt;angular-script.js&lt;/code&gt; would look like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return window.getAllAngularTestabilities().findIndex(x=&amp;gt;!x.isStable()) === -1

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

&lt;/div&gt;



&lt;p&gt;Check out this well written article that &lt;a href="https://www.swtestacademy.com/selenium-wait-javascript-angular-ajax/" rel="noopener noreferrer"&gt;explains how to wait for Angular page readiness using Selenium and gives a JSWaiter Java class&lt;/a&gt; that implements the correct approach for Angular &amp;gt; v5. &lt;/p&gt;

&lt;p&gt;You can also go the async way and run an async script in Selenium that will provide a &lt;code&gt;seleniumCallback&lt;/code&gt; callback function that your script will invoke when Angular is ready&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let rootElement = window.getAllAngularRootElements()[0];
let testability = window.getAngularTestability(rootElement);
testability.whenStable(seleniumCallback);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The catch is that this is only half the story, because any async process that you have running in your Angular app needs to indeed be done before Angular thinks that all testabilities are done and ready&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;If you have tried this above and it is still not working, it's more than likely because you have an async process running that prevents your app from ever attaining stability for test purposes. This is a particular true if you're using &lt;code&gt;setTimeout&lt;/code&gt; or &lt;code&gt;setInterval&lt;/code&gt;, let's say for example that as soon as the user logs in you launch a &lt;code&gt;setInterval&lt;/code&gt; to determine when their authentication or session tokens expires. If you trigger that a &lt;code&gt;setInterval&lt;/code&gt; as soon as your app boots up, you're toast in terms of testing if you don't take the proper measures as your app testability will never reach the stable point. That will more than likely mean a timeout if you're using Protractor or Selenium.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to get stable
&lt;/h2&gt;

&lt;p&gt;To attain stability for testing if you're using &lt;code&gt;setTimeout&lt;/code&gt; or &lt;code&gt;setInterval&lt;/code&gt; there are two things you can do:&lt;/p&gt;

&lt;h3&gt;
  
  
  Use ngZone.runOutsideAngular()
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;ngZone.runOutsideAngular&lt;/code&gt; if you're doing any work that does not require UI updates. If your work does require UI updates (where change detection is required), you can easily re-enter the Angular Zone by using &lt;code&gt;ngZone.run&lt;/code&gt;. &lt;a href="https://christianliebel.com/2016/11/angular-2-protractor-timeout-heres-fix/" rel="noopener noreferrer"&gt;Check out this article for an in -depth explanation of ngZone and how it works with testability&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Delay starting any timers until you really need to
&lt;/h3&gt;

&lt;p&gt;In my own case I was starting a timer as soon as the user logged in. I just delayed setting that timer until the Angular app is indeed ready for testing. This was a simple as delaying starting the timer in my authentication logic until Angular told testing was ready using a Testability on the Angular zone:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new Testability(ngZone).whenStable(()=&amp;gt;　{ 
        console.log("Now I am stable");
    　});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check out this Stackblitz for an idea on how to do that:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://stackblitz.com/edit/angular-o2kkac?" width="100%" height="500"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;With this simple change in the flow, the app reaches testing stability before the other processes can kick in. &lt;/p&gt;

&lt;p&gt;One last thing that might help in debugging this issue for you, how would you know that you have incomplete async tasks still running? Lucky for you, this blitz will help you setup your app to log all running microtasks in your Angular zone. This will allow you to check on any process you might have overlooked that is keeping your app from stabilizing initially:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://stackblitz.com/edit/zonejs-pending-tasks?" width="100%" height="500"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Also check out this &lt;a href="https://stackoverflow.com/questions/48627074/how-to-track-which-async-tasks-protractor-is-waiting-on" rel="noopener noreferrer"&gt;Stackoverflow discussion&lt;/a&gt; for some more context on this issue and how to solve it.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>protractor</category>
      <category>testing</category>
      <category>selenium</category>
    </item>
    <item>
      <title>A day in the life: how a frontend developer solves a "simple" bug</title>
      <dc:creator>Abou Kone</dc:creator>
      <pubDate>Sun, 23 Feb 2020 20:26:24 +0000</pubDate>
      <link>https://forem.com/codedivoire/a-day-in-the-life-how-a-frontend-developer-solves-a-simple-bug-3e98</link>
      <guid>https://forem.com/codedivoire/a-day-in-the-life-how-a-frontend-developer-solves-a-simple-bug-3e98</guid>
      <description>&lt;p&gt;I have been working lately with junior front end developers, as well as mentoring aspiring developers and one of the questions that they ask me is how to become a better/senior developer. That's a question that is hard for me to answer quantitatively but the one quality that I know about senior developers is their ability to solve problems, in a timely fashion. In this post I wanted to illustrate that aspect, but also to give an anecdotal insight into what a day might look like in the life of a front end developer, and the twists and turns that it can take to solve a seemingly simple problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bug
&lt;/h2&gt;

&lt;p&gt;I had implemented a new report page for one of our applications, where the user can create a spreadsheet like report by setting a few parameters. I say spreadsheet like because although it visually looks like a spreadsheet to the user, I implemented it as a flexbox based grid of individual grids, due to other requirements that made it difficult to achieve with a regular table. So far so good, except that to maintain the table appearance, I really need &lt;em&gt;pixel perfect&lt;/em&gt; coherence between the individual grids which after a little tweaking with padding and margins I achieved on Chrome on my Macbook. The code is deployed, everything looks good except for my colleagues running on Windows, they observed a slight shift one some of the columns, breaking the table illusion. To give you an idea, this is what they were observing:&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%2Fumuzbww9dov81jow10qe.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%2Fumuzbww9dov81jow10qe.png" alt="The bug" width="712" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Easy enough I told myself 8:30ish AM that morning, it's just another rendering issue, I just need to reproduce it and fix it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson 1: "It works on my machine" should never be a valid developer's answer to a bug. Unless you believe that other people at delusional, you should use it as a basis to start your investigation knowing that at least it works somewhere. It should never be from your perspective the end of it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgzlvmh1izqx0tkuugyr2.jpg" 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%2Fgzlvmh1izqx0tkuugyr2.jpg" alt="It Works On My Machine" width="422" height="585"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reproducing the issue on Chrome/Mac
&lt;/h2&gt;

&lt;p&gt;Like i said, my colleagues on Windows 10 were definitely seeing that bug so I first tried changing the resolution on my Chrome browser to see if it might be related to a responsiveness issue, no dice that way. Next I changed my focus to the operating system and thought that maybe the issue was related to a difference in the Chrome rendering depending on the OS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reproducing the issue on Chrome/Windows 10 with BrowserStack
&lt;/h2&gt;

&lt;p&gt;Next then was trying it in Chrome on a Windows 10 instance of BrowserStack. After many tries, again no dice. Let's try something else. I remembered I had a IE11/Windows 10 VM lying around for my (non Chrome) Edge. By this time, with standup included, it's 12:00ish PM.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reproducing the issue on Chrome/Windows 10 with VirtualBox
&lt;/h2&gt;

&lt;p&gt;I fired up the VM and tried to reproduce the issue, still no luck. I further probe with my colleagues and it became clear that the issue was resolution related. Their laptop was running on a 1920x1280 resolution and they were easily able to reproduce. i spent the next hour or so trying to get VirtualBox to render my Windows 10 VM guest using that same resolution to no avail. Somewhere in my Googling somebody mentioned using Parallels, which I had already installed. &lt;/p&gt;

&lt;h2&gt;
  
  
  Reproducing the issue on Chrome/Windows 10 with Parallels
&lt;/h2&gt;

&lt;p&gt;With Parallels fired up, I was quickly able to fire up a Windows 10 VM with the correct resolution, install Chrome, which led me to one of my favorite snark for my Windows colleagues&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1230929236082425859-774" src="https://platform.twitter.com/embed/Tweet.html?id=1230929236082425859"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1230929236082425859-774');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1230929236082425859&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;and lo and behold on accessing our dev server, the bug was there as soon as the page loaded. After a quick debugging session, I found the culprit behind the rendering issue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson 2: Be good at accepting when it's time to fold. If you're going down one road and it's not working, learn to quickly re-assess and try something different that will get you closer to your goal.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;While defining one of the borders for a particular grid, I had used the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;border-top: dashed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Chrome Mac, this translated actually to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;border-top: dashed 3px;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basically creating a 3px dashed border by default. I naively assumed that this was the default border with in Chrome. I found that in Windows, leaving Chrome to make the decision actually rendered as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;border-top: dashed 1px;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So there was always a 2px difference between the grids. Easy enough, now that I knew the problem, I wanted to switch back to my local env to fix and test the issue. It's around 3:00PM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson 3: With CSS, be as specific as possible when creating your rules and don't assume.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix
&lt;/h2&gt;

&lt;p&gt;Here again, while trying to work on the fix, I ran into another snag. Our Angular app runs on port 4200, and our API on 8080, which means that even after setting Parallels to be able to access my Mac localhost from my Windows VM, I was still unable to launch the app because of CORS issues. There are many different ways of solving this issue, i quickly tried:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Editing my &lt;code&gt;/etc/hosts&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;ngrok&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;but I decided to make use of the built-in Angular proxy configuration which we had previously used but discarded after enabling CORS on the API. What I thought would be a 1 minute affair turned into an hour when i realize the proxy configuration was not working!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Angular Proxy
&lt;/h2&gt;

&lt;p&gt;I was defining the different api proxy paths in &lt;code&gt;proxy.conf.json&lt;/code&gt; as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; "/api": {
    "target": "http://localhost:8080/api",
    "secure": false,
    "logLevel": "debug",
    "changeOrigin": true
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the application was running, trying to hit for example &lt;code&gt;/api/reports&lt;/code&gt; would proxy to &lt;code&gt;http://localhost:8080/api&lt;/code&gt; instead of &lt;code&gt;http://localhost:8080/api/reports&lt;/code&gt;. WTF? After re-reading the documentation many times, it finally jumped at me what I was doing wrong and the Angular/Webpack-dev-server people will correctly point out that ,y &lt;code&gt;target&lt;/code&gt; was wrong, I should not add the context path in the &lt;code&gt;target&lt;/code&gt; url but just the host. After changing the configuration to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; "/api": {
    "target": "http://localhost:8080",
    "secure": false,
    "logLevel": "debug",
    "changeOrigin": true
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;everything was peachy again and I was able to work and fix the issue properly. Psych! In the meantime, one of the Junior developers submitted a PR for which I had to do a code review, which lead to a video call to go over the code implication in depth since unbeknownst to the dev, his code as implemented would introduce a couple of regression bugs in the code. With that out of the way I was finally able to get back to the issue to fix and deploy, it's around 5:00PM now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson 4: Pay attention to details, especially syntax and spelling. That's why practices like pair programming and code reviews are important. Having a second set of eyes going over your code will help catch these little errors that we make that take too long for us to catch because we are used to our own code.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;What looked like a simple visual CSS bug created a journey that involved of course Google, VirtualBox and Parallels Desktop VMs, Browserstack, Angular and some high level networking (&lt;code&gt;etc/hosts&lt;/code&gt;). I've learned a few things during that process and here are some of the advice from that experience in that day that I would share with aspiring front end developers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whoever told you that as a front end developer, you would only be dealing with HTML, CSS and Javascript lied. As you have seen, producing applications require a lot more knowledge that usually, you can't teach directly. It's something that you pick up with experience.&lt;/li&gt;
&lt;li&gt;As a developer, your number one skill to develop is your problem solving. As illustrated here, solving code issues is sometimes not a straightforward affair. You will have to solve problems within problems.&lt;/li&gt;
&lt;li&gt;Take ownership of your work. You are ultimately responsible for the code you produce and it is your duty to ensure that it is of the highest quality.&lt;/li&gt;
&lt;li&gt;Embrace the process. This is what makes our industry so fun but so frustrating at the same time. Things will not always run right, even if (you think) you're doing everything right. Things will break or malfunction, even with your best efforts and part of your job is to figure out how to get them working again.&lt;/li&gt;
&lt;li&gt;For non-coders on the team, it's important to understand that things that look "simple" can turn out not to be so simple, either in implementation or in correcting when it comes to estimations.&lt;/li&gt;
&lt;li&gt;For my non English speaking friends, up your English skills. Like i said, navigating those issues required a lot of Googling and I can't imagine how much slower I would have gone had I not been proficient in English. There is a lot of good information out there and the absolute majority of it is in English, so having a good grasp of the language definitely helps.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With hindsight now, I went back to BrowserStack and it looks like you can launch a VM with a particular resolution, which would have saved me a couple of hours maybe if I had paid attention. At the end of the day, I found the whole experience funny but not atypical, and I learned some things from it. This is why wanted to share it with others, especially, more junior developers dealing with impostor syndrome to show you that being senior does not mean being all knowing and perfect, it just means that you're gonna "mess up in style" and usually be able to recover from those mess-ups quicker. What about you, do you have any interesting bug or experience that you could share?&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>angular</category>
      <category>productivity</category>
      <category>css</category>
    </item>
    <item>
      <title>How to internationalize a Yup validation schema in a React, Formik and react-i18next app</title>
      <dc:creator>Abou Kone</dc:creator>
      <pubDate>Thu, 13 Jun 2019 13:56:09 +0000</pubDate>
      <link>https://forem.com/codedivoire/how-to-internationalize-a-yup-validation-schema-in-a-react-formik-and-react-i18next-app-cj7</link>
      <guid>https://forem.com/codedivoire/how-to-internationalize-a-yup-validation-schema-in-a-react-formik-and-react-i18next-app-cj7</guid>
      <description>&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%2Fuploads%2Farticles%2Fksi1uututik83s9o9zae.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%2Fuploads%2Farticles%2Fksi1uututik83s9o9zae.png" width="800" height="449"&gt;&lt;/a&gt;&lt;br&gt;
&lt;span&gt;Internationalization of Yup validation schema with Formik and react-18next&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Anybody that had to deal with internationalization (shortened as i18n) knows that it can be a real pain if not handled properly, but in the modern Javascript stack, there exists libraries that remove a lot of that pain and actually make it a breeze. One of these libraries is &lt;a href="https://www.i18next.com/" rel="noopener noreferrer"&gt;i18next&lt;/a&gt;. If you work with React, you can’t do better than its react-i18next port for the way it seamlessly exposes the i18next API using all of the major React constructs (&lt;a href="https://react.i18next.com/latest/usetranslation-hook" rel="noopener noreferrer"&gt;Hooks&lt;/a&gt;, &lt;a href="https://react.i18next.com/latest/withtranslation-hoc" rel="noopener noreferrer"&gt;HOCs&lt;/a&gt;, &lt;a href="https://react.i18next.com/latest/translation-render-prop" rel="noopener noreferrer"&gt;Render Props&lt;/a&gt; and &lt;a href="https://react.i18next.com/latest/trans-component" rel="noopener noreferrer"&gt;Components&lt;/a&gt;). &lt;a href="https://jaredpalmer.com/formik/" rel="noopener noreferrer"&gt;Formik&lt;/a&gt; is form management library that promises to allow you to “build forms in React, without the tears” and I can say that indeed so far, my eyes have remained quite dry. Who says form also says validation, and Formik integrates easily with &lt;a href="https://github.com/jquense/yup" rel="noopener noreferrer"&gt;Yup&lt;/a&gt;, a JavaScript object schema validator and object parser. &lt;a href="https://github.com/jquense/yup/issues/159" rel="noopener noreferrer"&gt;Yup supports localization&lt;/a&gt;, but you have to&lt;br&gt;
provide it with a custom locale object, and I felt that the translation functionality should be single handedly handled by i18next. This article will explore how you can sync the translation of the validation errors in Yup when the user changes the selected page language.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Bug
&lt;/h3&gt;

&lt;p&gt;In the StackBlitz below, we have a basic setup of React, react-i18next, Formik and Yup. We display a form with a required email field defined in a Yup schema. This form can also be translated in French. To observe the bug in question in syncing the translation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click in the email field&lt;/li&gt;
&lt;li&gt;Click outside&lt;/li&gt;
&lt;li&gt;You should see a &lt;code&gt;Email is required&lt;/code&gt; error.&lt;/li&gt;
&lt;li&gt;Now click on the &lt;code&gt;Francais&lt;/code&gt;link.&lt;/li&gt;
&lt;li&gt;Everything on the page changes to the French translation except for the
validation error.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/react18next-yup-and-formik-basic-example-lbn26"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I suspect this happens because validation schema is initiated when the component renders with the language set to English initially, and on changing the language, the validation is not re-ran, causing the message to stay in English.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Fix
&lt;/h3&gt;

&lt;p&gt;Luckily the i18next exposes events, in particular the &lt;code&gt;languageChanged&lt;/code&gt; event that we can listen to and update the validation so the validation message can be translated. I initially implemented in a global useEffect hook (that I will share later in this article) that listened for this event and re-ran the form validation , but &lt;a href="https://github.com/jaredpalmer/formik/issues/1395" rel="noopener noreferrer"&gt;this issue on Github had a more elegant solution&lt;/a&gt;, setting all field&lt;br&gt;
with an error to be touched, which should trigger the field validation. The code in question is here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
    i18n.on('languageChanged', () =&amp;gt; {
        Object.keys(errors).forEach(fieldName =&amp;gt; {
            setFieldTouched(fieldName)
        })
    })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here is a blitz of the working translation:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/89mhe"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;errors&lt;/code&gt; object and &lt;code&gt;setFieldTouched&lt;/code&gt; function here are the &lt;code&gt;form.errors&lt;/code&gt; and &lt;code&gt;form.setFieldTouched&lt;/code&gt; properties of the Formik &lt;code&gt;form&lt;/code&gt; object passed in a prop. My requirements were different as I only wanted to show an error if the field had indeed been touched.&lt;/p&gt;
&lt;h3&gt;
  
  
  Use a hook
&lt;/h3&gt;

&lt;p&gt;In my particular case, I was dealing not only with field level validation bugs, but I also had nested forms where the same was happening. I created a global hook that takes in a Formik &lt;code&gt;form&lt;/code&gt; object and sets only the fields that have an error as touched. Here is the code:&lt;/p&gt;


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



&lt;p&gt;This way if the user had previously interacted with the field and gotten a validation error, the translation will re-render the form only with the existing errors translated. You can adjust depending on your business requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  WithTranslateFormErrors HOC
&lt;/h3&gt;

&lt;p&gt;I’ve created an HOC that you can add to your Formik form that will set this up for you. The code is pretty simple:&lt;/p&gt;


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


&lt;p&gt;And you would include it in your Formik form like this:&lt;/p&gt;


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


&lt;p&gt;You don’t need to use the HOC if you’re rendering your Formik form as a&lt;br&gt;
component. In that case, you can just use the &lt;code&gt;useTranslateFormErrors&lt;/code&gt; hook on its own in your render function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/react-i18next-helpers" rel="noopener noreferrer"&gt;This hook and HOC are available as part of the react-i18next-helpers library I recently released&lt;/a&gt;.&lt;/p&gt;




</description>
      <category>react</category>
      <category>internationalization</category>
      <category>translation</category>
    </item>
  </channel>
</rss>
