<?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: Matthew</title>
    <description>The latest articles on DEV Community by Matthew (@hahnmatthieu).</description>
    <link>https://dev.to/hahnmatthieu</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%2F205102%2Fd88f8b2d-2405-44f0-93bf-41eaa62577ee.jpg</url>
      <title>DEV Community: Matthew</title>
      <link>https://dev.to/hahnmatthieu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hahnmatthieu"/>
    <language>en</language>
    <item>
      <title>2FA with NestJs &amp; passeport using Google Authenticator</title>
      <dc:creator>Matthew</dc:creator>
      <pubDate>Thu, 07 Jul 2022 12:45:30 +0000</pubDate>
      <link>https://dev.to/hahnmatthieu/2fa-with-nestjs-passeport-using-google-authenticator-1l32</link>
      <guid>https://dev.to/hahnmatthieu/2fa-with-nestjs-passeport-using-google-authenticator-1l32</guid>
      <description>&lt;p&gt;I recently had to implement a two factor authentication on a project for my company and it was a whole new thing for me. Sure I had already used 2fa before but I had never implemented it.&lt;/p&gt;

&lt;p&gt;What is 2fa ? Well we all know that passwords aren't really secure enough to avoid security breaches so... &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;2FA is an extra layer of security used to make sure that people trying to gain access to an online account are who they say they are. First, a user will enter their username and a password. Then, instead of immediately gaining access, they will be required to provide another piece of information.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this case, I was asked to use the google authenticator app to generate a 2fa code that would be used to authenticate the user after the login step.&lt;/p&gt;

&lt;p&gt;I'll be using nestJs with passportjs. Here's the GitHub link if you want to check it out: &lt;a href="https://github.com/MatthieuHahn/2fa" rel="noopener noreferrer"&gt;https://github.com/MatthieuHahn/2fa&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Initializing the NestJS project with basic login password authentication
&lt;/h1&gt;

&lt;p&gt;Let's create a new nestJs project.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;nest new 2fa&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the authentication module
&lt;/h2&gt;

&lt;p&gt;First let's install the nestJs passeport dependencies and types. We'll need them in the next step.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn add @nestjs/passport passport passport-local&lt;/code&gt;&lt;br&gt;
&lt;code&gt;yarn add -D @types/passport-local&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then, we'll generate the authentication module, controller and service.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;nest generate resource authentication&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It'll ask you a few questions: choose REST API and then answer No (it's an auth module, we don't need CRUD endpoints)&lt;/p&gt;

&lt;p&gt;Then we'll create a user module, service and interface&lt;/p&gt;

&lt;p&gt;&lt;code&gt;nest generate module users&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;nest generate service users&lt;/code&gt;&lt;/p&gt;

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

export interface User {
  userId: number;
  username: string;
  password: string;
}


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

&lt;/div&gt;

&lt;p&gt;The users service will contain fake data, but, of course, you should add a data layer to persist data 😅&lt;/p&gt;

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

import { Injectable } from '@nestjs/common';
import { User } from "./user.entity";

@Injectable()
export class UsersService {
  private readonly users = [
    {
      userId: 1,
      username: 'john',
      password: 'changeme',
    },
    {
      userId: 2,
      username: 'maria',
      password: 'guess',
    },
  ];

  async findOne(username: string): Promise&amp;lt;User | undefined&amp;gt; {
    return this.users.find(user =&amp;gt; user.username === username);
  }
}


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

&lt;/div&gt;

&lt;p&gt;Let's add a validateUser method that will check if the user and password that we'll send are a match with our data. &lt;/p&gt;

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

import { Injectable } from '@nestjs/common';
import { UsersService } from "../users/users.service";
import { User } from "../users/user.entity";

@Injectable()
export class AuthenticationService {
  constructor(private usersService: UsersService) {
  }

  async validateUser(email: string, pass: string): Promise&amp;lt;Partial&amp;lt;User&amp;gt;&amp;gt; {
    const user = await this.usersService.findOne(email);
    try {
      // Of course, we should consider encrypting the password
      const isMatch = pass === user.password;
      if (user &amp;amp;&amp;amp; isMatch) {
        const { password: _, ...userWithoutPassword } = user;

        return userWithoutPassword;
      }
    } catch (e) {
      return null;
    }
  }
}



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

&lt;/div&gt;

&lt;p&gt;If you are not familiar with nestJs, this framework provides a UseGuard decorator that will act as an auth middleware which can rely on the passportjs library. So let's use this feature and the nestJs passport library to manage the user/password login.&lt;/p&gt;

&lt;p&gt;First we define the local auth guard which extends the passportjs local strategy.&lt;/p&gt;

&lt;p&gt;local-auth.guard.ts&lt;/p&gt;

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

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}



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

&lt;/div&gt;

&lt;p&gt;And then we define the local authentication strategy. The constructor contains the auth fields that will be sent by the front-end via the login POST route (email, password).&lt;br&gt;
The validate method will use the validateUser method we created earlier. If it returns no user, then it will throw a 401 Unauthorized error, else it will return the user without the password.&lt;/p&gt;

&lt;p&gt;local.strategy.ts&lt;/p&gt;

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

import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthenticationService } from '../authentication.service';
import { User } from '../../users/user.entity';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private authenticationService: AuthenticationService) {
    super({
      usernameField: 'email',
      passwordField: 'password',
    });
  }

  async validate(email: string, password: string): Promise&amp;lt;Partial&amp;lt;User&amp;gt;&amp;gt; {
    const userWithoutPsw = await this.authenticationService.validateUser(email, password);
    if (!userWithoutPsw) {
      throw new UnauthorizedException();
    }
    return userWithoutPsw;
  }
}


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

&lt;/div&gt;

&lt;p&gt;We can now create the login method in the authentication controller and service. For now it'll only return the user's email. But later on, we'll add a Jwt access token&lt;/p&gt;

&lt;p&gt;First we add the login method to the authentication service.&lt;/p&gt;

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

async login(userWithoutPsw: Partial&amp;lt;User&amp;gt;, isTwoFactorAuthenticated = false) {
    const payload = {
      email: userWithoutPsw.email,
      isTwoFactorAuthenticationEnabled: !!userWithoutPsw.isTwoFactorAuthenticationEnabled,
      isTwoFactorAuthenticated,
    };

    return {
      email: payload.email,
    };
  }


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

&lt;/div&gt;

&lt;p&gt;Then we create the controller route with the LocalAuthGuard&lt;/p&gt;

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

@UseGuards(LocalAuthGuard)
@Post('login')
@HttpCode(200)
async login(@Request() req) {
  const userWithoutPsw: Partial&amp;lt;User&amp;gt; = req.user;

  return this.authenticationService.login(userWithoutPsw);
}


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

&lt;/div&gt;

&lt;p&gt;Ok, so now, if we send a post request on the /authentication/login route with correct credentials, it will return the user's email. Let's add the Jwt management now.&lt;/p&gt;

&lt;p&gt;First we add the nestJs Jwt package.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn add @nestjs/jwt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then we have to register the JwtModule in the Authentication module in order to be able to use it. The secret should, of course, be secret and in an .env file.&lt;/p&gt;

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

JwtModule.register({
    secret: 'secret',
    signOptions: { expiresIn: '1d' },
  })


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

&lt;/div&gt;

&lt;p&gt;Then we just have to add the JwtService to the AuthenticationService and use it to generate the access_token we'll return to the front-end.&lt;br&gt;
Here's what the authentication service should look like now.&lt;/p&gt;

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

import { Injectable } from '@nestjs/common';
import { UsersService } from "../users/users.service";
import { User } from "../users/user.entity";
import { JwtService } from "@nestjs/jwt";

@Injectable()
export class AuthenticationService {
  constructor(private usersService: UsersService, private jwtService: JwtService) {
  }

  async validateUser(email: string, pass: string): Promise&amp;lt;Partial&amp;lt;User&amp;gt;&amp;gt; {
    const user = await this.usersService.findOne(email);
    try {
      // Of course, we should consider encrypting the password
      const isMatch = pass === user.password;
      if (user &amp;amp;&amp;amp; isMatch) {
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        const { password: _, ...userWithoutPassword } = user;
        return userWithoutPassword;
      }
    } catch (e) {
      return null;
    }
  }

  async login(userWithoutPsw: Partial&amp;lt;User&amp;gt;) {
    const payload = {
      email: userWithoutPsw.email,
    };

    return {
      email: payload.email,
      access_token: this.jwtService.sign(payload),
    };
  }
}


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

&lt;/div&gt;

&lt;p&gt;Now the frontend has a Jwt token it'll be able to use to authenticate requests to the backend. But how will the backend manage the Authorization token ?&lt;br&gt;
Well, let's create a JwtAuthGuard using passportjs jwt package.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn add passport-jwt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We can now create the jwt strategy which is based on passportjs.&lt;/p&gt;

&lt;p&gt;jwt.strategy.ts&lt;/p&gt;

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

import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { UsersService } from '../../users/users.service';
import { TokenPayload } from '../token-payload.entity';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(private readonly userService: UsersService) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: 'secret',
    });
  }

  async validate(payload: TokenPayload) {
    const user = await this.userService.findOne(payload.email);

    if (user) {
      return user;
    }
  }
}



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

&lt;/div&gt;

&lt;p&gt;And create the JwtAuthGuard.&lt;/p&gt;

&lt;p&gt;jwt-auth.guard.ts&lt;/p&gt;

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

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}


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

&lt;/div&gt;

&lt;p&gt;So for now, we have a complete basic authentication using JWT to authenticate requests. But as we said before, it is based on a user/password login and therefore it is not very secure. So let's add the two factor authentication.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two factor authentication
&lt;/h2&gt;

&lt;p&gt;Here's the login flow for 2fa authentication:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The user logs in with his email and password&lt;/li&gt;
&lt;li&gt;If the 2fa is not enabled, he can enable it using the turn-on route. This will generate a QrCode that the user will scan with the google authenticator app. &lt;/li&gt;
&lt;li&gt;The use then uses the random code the app has generated to authenticate&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Creating the 2fa system
&lt;/h3&gt;

&lt;p&gt;First we have to create a unique secret for every user that turns on 2fa, but we'll also need a special otp authentication url that we'll be using later to create a QrCode. The otplib package is a good match, so let's install it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn add otplib&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We should also update the user interface and add the twoFactorAuthenticationSecret property.&lt;/p&gt;

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

export interface User {
  userId: number;
  email: string;
  username: string;
  password: string;
  twoFactorAuthenticationSecret: string;
}


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

&lt;/div&gt;

&lt;p&gt;Then we create a method to generate the secret and otpAuthUrl in the authentication service and return both of them. The AUTH_APP_NAME is the name that will appear in the google authenticator app.&lt;/p&gt;

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

async generateTwoFactorAuthenticationSecret(user: User) {
    const secret = authenticator.generateSecret();

    const otpauthUrl = authenticator.keyuri(user.email, 'AUTH_APP_NAME', secret);

    await this.usersService.setTwoFactorAuthenticationSecret(secret, user.userId);

    return {
      secret,
      otpauthUrl
    }
  }


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

&lt;/div&gt;

&lt;p&gt;We have to update the user with the secret that has just been generated. Once again, this should all be in a database.&lt;/p&gt;

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

  async setTwoFactorAuthenticationSecret(secret: string, userId: number) {
    this.users.find(user =&amp;gt; user.userId === userId).twoFactorAuthenticationSecret = secret;
  }


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

&lt;/div&gt;

&lt;p&gt;Now, we can generate the QrCode that will be used to add our application to the google authenticator app.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn add qrcode&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let's add the generate method in the authentication service.&lt;/p&gt;

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

  import { toDataURL } from 'qrcode';

  async generateQrCodeDataURL(otpAuthUrl: string) {
    return toDataURL(otpAuthUrl);
  }


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

&lt;/div&gt;

&lt;p&gt;Now we need to offer the possiblity for the user to turn on the 2fa. So let's add another property to the user interface.&lt;/p&gt;

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

export interface User {
  userId: number;
  email: string;
  username: string;
  password: string;
  twoFactorAuthenticationSecret: string;
  isTwoFactorAuthenticationEnabled: boolean;
}


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

&lt;/div&gt;

&lt;p&gt;Add the turnOn method in the users service&lt;/p&gt;

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

  async turnOnTwoFactorAuthentication(userId: number) {
    this.users.find(user =&amp;gt; user.userId === userId).isTwoFactorAuthenticationEnabled = true;
  }


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

&lt;/div&gt;

&lt;p&gt;Add the method that will verify the authentication code with the user's secret&lt;/p&gt;

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

isTwoFactorAuthenticationCodeValid(twoFactorAuthenticationCode: string, user: User) {
    return authenticator.verify({
      token: twoFactorAuthenticationCode,
      secret: user.twoFactorAuthenticationSecret,
    });
  }


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

&lt;/div&gt;

&lt;p&gt;Add the turn on route in the authentication controller&lt;/p&gt;

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

 @Post('2fa/turn-on')
  @UseGuards(JwtAuthGuard)
  async turnOnTwoFactorAuthentication(@Req() request, @Body() body) {
    const isCodeValid =
      this.authenticationService.isTwoFactorAuthenticationCodeValid(
        body.twoFactorAuthenticationCode,
        request.user,
      );
    if (!isCodeValid) {
      throw new UnauthorizedException('Wrong authentication code');
    }
    await this.usersService.turnOnTwoFactorAuthentication(request.user.id);
  }


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Logging in with 2fa
&lt;/h3&gt;

&lt;p&gt;Let's add a login with 2fa method in the authentication service. The difference with the default login function is that we add the 2fa status in the payload. &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

  async loginWith2fa(userWithoutPsw: Partial&amp;lt;User&amp;gt;) {
    const payload = {
      email: userWithoutPsw.email,
      isTwoFactorAuthenticationEnabled: !!userWithoutPsw.isTwoFactorAuthenticationEnabled,
      isTwoFactorAuthenticated: true,
    };

    return {
      email: payload.email,
      access_token: this.jwtService.sign(payload),
    };
  }


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

&lt;/div&gt;

&lt;p&gt;We can now create the 2fa authentication route in the controller. If the code sent in the post body is valid, then we try to login with 2fa else we throw an error.&lt;/p&gt;

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

@Post('2fa/authenticate')
  @HttpCode(200)
  @UseGuards(JwtAuthGuard)
  async authenticate(@Request() request, @Body() body) {
    const isCodeValid = this.authenticationService.isTwoFactorAuthenticationCodeValid(
      body.twoFactorAuthenticationCode,
      request.user,
    );

    if (!isCodeValid) {
      throw new UnauthorizedException('Wrong authentication code');
    }

    return this.authenticationService.loginWith2fa(request.user);
  }


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

&lt;/div&gt;

&lt;p&gt;It is now possible to create an AuthGuard strategy based on Jwt and the 2fa status. If the 2fa is not turned on then we can rely on the jwt only, if the 2fa is enabled then we check if the user is 2fa authenticated.&lt;/p&gt;

&lt;p&gt;jwt-2fa.strategy.ts&lt;/p&gt;

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

import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { UsersService } from '../../users/users.service';

@Injectable()
export class Jwt2faStrategy extends PassportStrategy(Strategy, 'jwt-2fa') {
  constructor(private readonly userService: UsersService) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: 'secret',
    });
  }

  async validate(payload: any) {
    const user = await this.userService.findOne(payload.email);

    if (!user.isTwoFactorAuthenticationEnabled) {
      return user;
    }
    if (payload.isTwoFactorAuthenticated) {
      return user;
    }
  }
}



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

&lt;/div&gt;

&lt;p&gt;jwt-2fa-auth.guard.ts&lt;/p&gt;

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

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class Jwt2faAuthGuard extends AuthGuard('jwt-2fa') {}


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

&lt;/div&gt;

&lt;p&gt;Let's see how this goes right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;So first we'll do a POST request to log in with the user and password:&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%2Fuploads%2Farticles%2Frkygvo4iai4s9euvk9rr.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%2Frkygvo4iai4s9euvk9rr.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will return the following:&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%2Fuploads%2Farticles%2Fb0qo3gnfsa68iialgqd2.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%2Fb0qo3gnfsa68iialgqd2.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, we need to get the QrCode to add our app to the google authenticator app&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%2Fuploads%2Farticles%2F2wwja2hfavmndtgfnt4i.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%2F2wwja2hfavmndtgfnt4i.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will return a base64 data url which in turn will happen to be a QrCode&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%2Fuploads%2Farticles%2Fi1gpy9ome35jjeyn8reh.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%2Fi1gpy9ome35jjeyn8reh.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you scan this with the Google Authenticator App it should add your app:&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%2Fuploads%2Farticles%2Fung8ipxi26gmjpuv3kwd.jpeg" 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%2Fung8ipxi26gmjpuv3kwd.jpeg" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And then you should be able to call the authenticate route with the current code from the google authenticator app&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>authentication</category>
      <category>beginners</category>
      <category>typescript</category>
    </item>
    <item>
      <title>My take on clean code</title>
      <dc:creator>Matthew</dc:creator>
      <pubDate>Wed, 30 Dec 2020 14:06:40 +0000</pubDate>
      <link>https://dev.to/hahnmatthieu/my-take-on-clean-code-3d4</link>
      <guid>https://dev.to/hahnmatthieu/my-take-on-clean-code-3d4</guid>
      <description>&lt;p&gt;I recently encountered a PHP project that made me want to write about &lt;strong&gt;clean code&lt;/strong&gt;. &lt;br&gt;
SitRep: One of our clients has a website that needs some bug fixing and some features to be added. Once I had cloned the GitHub repo, I took a look at how the code was written and  my reaction was:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/Is6fBDegr2HUA/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/Is6fBDegr2HUA/giphy.gif" alt="holy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ok, slight exaggeration here 😅, but you get me.&lt;/p&gt;

&lt;p&gt;So here are my thoughts about how useful it is to write clean code&lt;/p&gt;
&lt;h1&gt;
  
  
  What is &lt;em&gt;clean code&lt;/em&gt; anyway ?
&lt;/h1&gt;

&lt;p&gt;I guess thousands of lines could be written about this topic, but in a nutshell, I'd say clean code is code that is going to be easy to maintain. Easy to maintain not only by yourself in one week, but probably other people months later when you're no longer here to explain it.&lt;/p&gt;

&lt;p&gt;Ok now let's get on with it then.&lt;/p&gt;
&lt;h1&gt;
  
  
  Readability
&lt;/h1&gt;

&lt;p&gt;To me, this is probably the most important in writing clean code. &lt;br&gt;
The code you write MUST be readable by another human being without generating this kind of reaction:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/ef7GqsDYDIKFa/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/ef7GqsDYDIKFa/giphy.gif" alt="crap"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Naming variables and functions
&lt;/h3&gt;

&lt;p&gt;a, b, c, test, thing, ... are not good variable names, that's pretty obvious, but I still occasionally see them around 😅. I recently started to look into Golang and it seems quite frequent to see badly named variables there 🤔.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Don't
function calcTwt(a, b, c) {
  return a * b * c;
}

// Do
function caculateTotalWithTaxes(quantity, unitPrice, taxes) {
  return quantity * unitPrice * taxes;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, no need to overdo it, keep names short but understandable.&lt;/p&gt;

&lt;p&gt;Also, there are many standards about naming variables already out there. For example, boolean will often be written &lt;code&gt;isOpened&lt;/code&gt;, &lt;code&gt;areOpened&lt;/code&gt;, &lt;code&gt;hasRead&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's a pretty good article about naming stuff: &lt;a href="https://hackernoon.com/the-art-of-naming-variables-52f44de00aad"&gt;https://hackernoon.com/the-art-of-naming-variables-52f44de00aad&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep your functions simple
&lt;/h3&gt;

&lt;p&gt;Your functions should only do what they say they do. For example, if you call your function &lt;code&gt;getUser&lt;/code&gt; and pass an &lt;code&gt;id&lt;/code&gt; param to it which would be &lt;code&gt;getUser(id)&lt;/code&gt;, it should only fetch and return the user which has this id, and that's ALL.&lt;/p&gt;

&lt;p&gt;Also, if your function is too long and does many different actions, it's probably a sign that you should split it into multiple smaller functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Formatting
&lt;/h3&gt;

&lt;p&gt;Here are a few tips about formatting your code:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Keep your files from being too long&lt;/li&gt;
&lt;li&gt;Limit the length of lines&lt;/li&gt;
&lt;li&gt;Last but not least, comply by the rules set by your team&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Coding principles
&lt;/h1&gt;

&lt;h3&gt;
  
  
  DRY
&lt;/h3&gt;

&lt;p&gt;Don't Repeat Yourself. &lt;/p&gt;

&lt;p&gt;That's pretty straight forward ain't it. It states that every piece of code you write should only have one clear representation in your project's codebase.&lt;br&gt;
In other words, you shouldn't write the same piece of code twice. If you are, then your code is going to be more difficult to maintain.&lt;/p&gt;

&lt;p&gt;Here's a simple example, you have a list of users and want to display the concatenation of the firstName and lastName.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const users = [
  {
    id: 1,
    firstName: 'Luke',
    lastName: 'Cage',
  },
  {
    id: 2,
    firstName: 'Jessica',
    lastName: 'Jones'
  }, 
  {
    id: 3,
    firstName: 'The incredible',
    lastName: 'Hulk',
  }
]

// Don't

console.log(`${users[0].firstName} ${users[0].lastName}`);
console.log(`${users[1].firstName} ${users[1].lastName}`);
console.log(`${users[2].firstName} ${users[2].lastName}`);

// Do
function displayUserName(user) {
  console.log(`${user.firstName} ${user.lastName}`);
}

users.forEach(displayUserName);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  KISS
&lt;/h3&gt;

&lt;p&gt;Keep It Simple Stupid is a design principle noted by the U.S. Navy in 1960 meaning you should avoid unnecessary complexity as much as possible. If things are kept simple, they are easier to understand and therefore easier to maintain.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/KISS_principle"&gt;https://en.wikipedia.org/wiki/KISS_principle&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/U9P3Sn5BFp6Tx11juW/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/U9P3Sn5BFp6Tx11juW/giphy.gif" alt="kiss"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's a silly example, but it should make it clear to you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Don't
function dayOfWeek(dayNumber) {
  switch(dayNumber) {
    case 1:
      return 'Monday';
      break;
    case 2:
      return 'Thuesday';
      break;
    case 3:
      return 'Wednesday';
      break;
    case 4:
      return 'Thursday';
      break;
    case 5:
      return 'Friday';
      break;
    case 6:
      return 'Saturday';
      break;
    case 7:
      return 'Sunday';
      break;
    default: 
      return null;
  }
}

// Do
function dayOfWeek(dayNumber) {
  if (dayNumber &amp;lt; 1 || dayNumber &amp;gt; 7) return null;

  const weekdays = [
   'monday',
   'thuesday',
   'wednesday',
   'thursday',
   'friday',
   'saturday',
   'sunday',
  ];

  return weekdays[dayNumber - 1];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  YAGNI
&lt;/h3&gt;

&lt;p&gt;You Aren't Gonna Need It. &lt;/p&gt;

&lt;p&gt;One thing I learnt in my beginner years was not to write functions before you need them. Otherwise, you're probably going to create dead code.&lt;/p&gt;

&lt;p&gt;For example if you're writing a user class, don't assume you might later need a method to concatenate the first name and the last name, only write it when you need it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One way&lt;/strong&gt; of achieving this principle is to write the code as you're going.  &lt;/p&gt;

&lt;p&gt;Imagine you want to display a list of users in an MVC language like angular, then you should theoretically write things in this order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The view --&amp;gt; needs a &lt;code&gt;users&lt;/code&gt; variable from the controller&lt;/li&gt;
&lt;li&gt;The controller --&amp;gt; needs a &lt;code&gt;getUsers&lt;/code&gt; function from the service&lt;/li&gt;
&lt;li&gt;The service --&amp;gt; needs a &lt;code&gt;fetch&lt;/code&gt; function from the httpService&lt;/li&gt;
&lt;li&gt;HttpService --&amp;gt; And so on ...&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Writing your code in this order should prevent you from creating functions you won't be using.&lt;/p&gt;

&lt;p&gt;Please keep in mind that this is my way of avoiding to write dead code, you could also go "bottom up", start with the services and end up with the view.&lt;/p&gt;

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

&lt;p&gt;I voluntarily kept this pretty short, I could, of course, go into details for all of those topics but the idea was to give a hint to beginners on how to keep their code clean.&lt;br&gt;
You should always bear in mind that all teams have their standards of writing code.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>codequality</category>
      <category>cleancode</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Using NgRx with Angular</title>
      <dc:creator>Matthew</dc:creator>
      <pubDate>Sat, 18 Jul 2020 19:03:32 +0000</pubDate>
      <link>https://dev.to/hahnmatthieu/using-ngrx-with-angular-4egk</link>
      <guid>https://dev.to/hahnmatthieu/using-ngrx-with-angular-4egk</guid>
      <description>&lt;p&gt;&lt;em&gt;As I just moved from the country I've lived in for my whole life, France 🇫🇷, to Canada 🇨🇦, I had to start a new job 🥳. I'm back to being a Software Developer, and that definitely feels great. I have learnt quite a few things in a few weeks, thanks to the incredible team working at &lt;a href="https://kumojin.com/"&gt;Kumojin&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In this article I wanted to share what I learnt while working on an Angular project using NgRx. I was really new to NgRx although having been working with angular for a few years and what a discovery ! 🚀&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What is NgRx 🤷🏼‍♂️ ?
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;NgRx is a framework for building reactive applications in Angular. &lt;a href="https://ngrx.io/docs"&gt;https://ngrx.io/docs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;😲&lt;/p&gt;

&lt;p&gt;A reactive application is an application that depends on data streams and propagation of change.&lt;/p&gt;

&lt;p&gt;Eg.:&lt;br&gt;
&lt;em&gt;You want to build a component which needs to fetch a list of products to display it. If a product is added later to this list by some other component, you won't need to add anymore logic to the first component in order to manage the change in the state.&lt;/em&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  So, should I use it then ?
&lt;/h1&gt;

&lt;p&gt;Well, as most things in tech, there are cases where it is not really suited, and some where it's the best bet.&lt;/p&gt;

&lt;p&gt;I wouldn't recommend using NgRx if the app you are building doesn't have many user interactions, isn't too complex. In this case you probably won't need it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3o7aCWDyW0PJCsxHna/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3o7aCWDyW0PJCsxHna/giphy.gif" alt="Alt text of image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a simple application I would clearly recommended to store the states in the services and call the services from the components.&lt;/p&gt;

&lt;p&gt;However, if a state is accessed by multiple components, is updated with external data, needs to be used when re-entering a route or if the state gets modified by the actions of other sources then it is a hell of a good deal. It also brings quite a bit of structure to the project.&lt;/p&gt;

&lt;p&gt;In other terms, it is important to understand that using NgRx will add quite a bit of complexity to the project's structure, so the choice has to be thought through. &lt;br&gt;
Also, it is not that easy to understand when you are not used to managing states this way. I found it a bit disconcerting at first, but after a few days, I really got the hang of it.&lt;/p&gt;
&lt;h1&gt;
  
  
  Ok, then how does it work ?
&lt;/h1&gt;

&lt;p&gt;Here's a quick diagram I got from GitHub that I found pretty clear (once it was explained to me 😂). I recommend you go back to this diagram at each section of this article, it should become clearer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iuLqo9pp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/6563379/61843964-c1f05e80-ae6b-11e9-9542-800c34a1a2f9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iuLqo9pp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/6563379/61843964-c1f05e80-ae6b-11e9-9542-800c34a1a2f9.png" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Actions
&lt;/h2&gt;

&lt;p&gt;Actions are unique events which can happen in you app. They have a type and can eventually carry properties to add some context.&lt;/p&gt;

&lt;p&gt;Eg:&lt;br&gt;
&lt;em&gt;I need my component to fetch products as earlier. Instead of directly calling the products service and wait for the result, the component will dispatch an action&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Without NgRx:
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;products.component.ts&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;constructor(private productService: ProductService) {
  this.productService.getAll()
    .subscribe((products) =&amp;gt; {
       this.products = products;
    });
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  With NgRx:
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;products.action.ts&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Enumerate the actions, it's cleaner when you need them elsewhere.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export enum ProductActionTypes {
  FETCH_PRODUCTS = '[Products] Fetch products',
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Implement the action (Add a type, and eventually some context)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class FetchProducts implements Action {
  readonly type = ProductActionTypes.FETCH_PRODUCTS;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Export the actions type, it'll be useful later on&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export type ProductsActions =
  | FetchProducts
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;products.component.ts&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;constructor(private readonly store: Store) {
  this.store.dispatch(new FetchProducts());
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Ok then, we have started to isolate the component from the service by dispatching an action, what happens next ? Well, actions are processed by reducers and effects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reducers
&lt;/h2&gt;

&lt;p&gt;Reducers manage the state transitions by listening to the actions which are dispatched.&lt;br&gt;
If you think about the example you'll see there are in fact 3 different states:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;State 1: The products are being fetched&lt;/li&gt;
&lt;li&gt;State 2: The products have been fetched with success&lt;/li&gt;
&lt;li&gt;State 3: The products fetching failed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In fact there even is a State 0, when the state is initialized and nothing has happened yet.&lt;/p&gt;

&lt;p&gt;We will create as many actions as they are different states in the reducer as the reducer states depend on the actions &lt;/p&gt;

&lt;p&gt;&lt;em&gt;products.actions.ts&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export enum ProductActionTypes {
  FETCH_PRODUCTS = '[Products] Fetch products',
  FETCH_PRODUCTS_SUCCESS = '[Products] Fetch products success',
  FETCH_PRODUCTS_FAIL = '[Products] Fetch products fail',
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class FetchProducts implements Action {
  readonly type = ProductActionTypes.FETCH_PRODUCTS;
}

export class FetchProductsSuccess implements Action {
  readonly type = ProductActionTypes.FETCH_PRODUCTS_SUCCESS;

  constructor(public products: Product[]) { }
}

export class FetchProductsFail implements Action {
  readonly type = ProductActionTypes.FETCH_PRODUCTS_FAIL;

  constructor(public payload: ErrorData) { }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export type ProductsActions =
  | FetchProducts
  | FetchProductsSuccess
  | FetchProductsFail;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;products.reducer.ts&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;First, let's declare the state properties and the initial state (State 0 😉)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export interface ProductsState {
  loading: boolean;
  products: Product[];
}

export const productsInitialState: ProductsState = {
  loading: false,
  products: null,
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then let's listen for actions and manage the state accordingly&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export function productsReducer(
  state = productsInitialState,
  action: ProductActions
): ProductsState {
  switch (action.type) {
    case ProductActionTypes.FETCH_PRODUCTS: {
      return {
        ...state,
        loading: true,
      };
    }

    case ProductActionTypes.FETCH_PRODUCTS_SUCCESS: {
      return {
        ...state,
        products: action.products,
        loading: false,
        loaded: true,
      };
    }

    case ProductActionTypes.FETCH_PRODUCTS_FAIL: {
      return {
        ...state,
        loading: false,
        loaded: false,
      };
    }

    default: {
      return state;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Effects
&lt;/h2&gt;

&lt;p&gt;Once actions have been dispatched and states have been initialized, we need to take care of the side effects.&lt;/p&gt;

&lt;p&gt;Effects are what's going to help you isolate services from components by listening to the dispatched actions. They can also trigger new events by dispatching new actions.&lt;/p&gt;

&lt;p&gt;Let's explain it with an example. I want my products service to be called when the "Fetch products" action is dispatched, but I also want it to dispatch a new action once it has succeeded or failed don't I ?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;products.effects.ts&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;First let's inject the services I need. Here, &lt;code&gt;Actions&lt;/code&gt; is a stream which contains all the dispatched actions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;constructor(
    private actions$: Actions,
    private readonly productsService: ProductsService,
    private readonly errorService: ErrorService,
  ) { }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then let's create our first effect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Effect()
public fetchProducts$ = this.actions$.pipe(
    ofType&amp;lt;FetchProducts&amp;gt;(ProductActionTypes.FETCH_PRODUCTS),
    switchMap(() =&amp;gt; this.productsService.fetchProducts().pipe(
      map((products: Product[]) =&amp;gt; new FetchProductsSuccess(products)),
      catchError((error: ErrorData) =&amp;gt; of(new FetchProductsFail(error)))),
    ),
  );
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What this effect is saying is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Listen to all dispatched action for an action with the "FetchProduct" type&lt;/li&gt;
&lt;li&gt;If an action of this type is dispatched, then call the products service to fetch products.&lt;/li&gt;
&lt;li&gt;If the service call is a success then dispatch a &lt;code&gt;FetchProductsSuccess&lt;/code&gt; action (passing it the result of the service call)&lt;/li&gt;
&lt;li&gt;If the service call fails, then dispatch a &lt;code&gt;FetchProductsFail&lt;/code&gt; action. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The action dispatched on success doesn't need an effect as it's only there to change the products state, remember ?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case '[Products] Fetch products success': {
      return {
        ...state,
        products: action.products,
        loading: false,
      };
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So, I dispatch a &lt;code&gt;FetchProductsSuccess&lt;/code&gt; action, feed it the data I just got from the service, and guess who's waiting for it: the reducer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/12NUbkX6p4xOO4/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/12NUbkX6p4xOO4/giphy.gif" alt="Alt text of image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, in this case, I created an effect to display an error message if the service fails to fetch the products. By default, an effect will always dispatch a new action, but you can override this by adding &lt;code&gt;{ dispatch: false }&lt;/code&gt;. My effect will therefore call the service and then nothing more happens.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Effect({ dispatch: false })
public fetchProductsFail$ = this.actions$.pipe(
    ofType&amp;lt;FetchProductsFail&amp;gt;(ProductActionTypes.FETCH_PRODUCTS_FAIL),
    map((action: FetchProductsFail) =&amp;gt; action.payload),
    tap((error: ErrorData) =&amp;gt; this.errorService.displayError(error)),
  );
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This brings us to the last step "Selectors". If you remember, in our component, we dispatched the action &lt;code&gt;this.store.dispatch(new FetchProducts());&lt;/code&gt;. That's the way to go, but, nobody in this component is watching for the state changes, so nothing visible should happen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Selectors
&lt;/h2&gt;

&lt;p&gt;Selectors are function that will help you get the "pieces" of your states you need.&lt;/p&gt;

&lt;p&gt;In my example, I need to get the products and the loading state of my products state.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;products.selector.ts&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const getProductsState = createFeatureSelector&amp;lt;ProductsState&amp;gt;('products');

export const getLoading = createSelector(
  getProductsState,
  (state: ProductsState) =&amp;gt; state.loading
);

export const getProducts = createSelector(
  getProductsState,
  (state: ProductsState) =&amp;gt; state.products
);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To use a selector, you have to call the store like follows:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;products.component.ts&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public products$: Observable&amp;lt;Product[]&amp;gt; = this.store.pipe(
    select(getProducts),
  );

public loading$: Observable&amp;lt;boolean&amp;gt; = this.store.pipe(
    select(getLoading)
  );
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Using the async pattern in the Html file prevents from having to clean up the observables in the component's onDestroy method. The cleaning is done automatically when leaving the component.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;product.component.html&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;p *ngIf="loading$ | async"&amp;gt; Loading &amp;lt;/p&amp;gt;
&amp;lt;ul *ngIf="products$ | async as products"&amp;gt;
  &amp;lt;li *ngFor="let product of products"&amp;gt;{{ product.name }}&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Declaring the store in the App module
&lt;/h2&gt;

&lt;p&gt;Note the StoreDevtoolsModule which is very useful when debugging a NgRx application 👌.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[...]
import { reducers } from './core/store/reducers';
import { effects } from './core/store/effects';
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  imports: [
    [...],
    StoreModule.forRoot(reducers, { runtimeChecks: { strictStateImmutability: true, strictActionImmutability: true } }),
    EffectsModule.forRoot(effects),
    StoreDevtoolsModule.instrument(),
  ]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



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

&lt;p&gt;This is the end of this small introduction to NgRx. You obviously can do much more stuff with it, like manage your app router, use entities to manage state collections and plenty of other magical things.&lt;br&gt;
As you can see, for just a simple webapp, it might be just too complex to setup. In the example above, I only did the work for one state, one component and a few actions. &lt;br&gt;
The magic really starts operating when your app becomes complex, things are always at the place you expect them to be, your components are isolated from the services and using the devtools, you can easily debug and see the action/data flow of your app.&lt;br&gt;
Just below are some links including the GitHub project for the example above.&lt;br&gt;
I hope you appreciated my first tech article, I'll be happy to discuss it over even if you disagree 😇.&lt;/p&gt;

&lt;h1&gt;
  
  
  Links
&lt;/h1&gt;

&lt;p&gt;Live example: &lt;a href="https://5f1246c2a5e2da029b87fe44--hungry-bhabha-4ea98a.netlify.app/"&gt;https://5f1246c2a5e2da029b87fe44--hungry-bhabha-4ea98a.netlify.app/&lt;/a&gt;&lt;br&gt;
GitHub: &lt;a href="https://github.com/MatthieuHahn/ngrx"&gt;https://github.com/MatthieuHahn/ngrx&lt;/a&gt;&lt;br&gt;
NgRx full documentation: &lt;a href="https://ngrx.io/"&gt;https://ngrx.io/&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Credits
&lt;/h1&gt;

&lt;p&gt;I'd really like to thank Julien and Lukasz from the &lt;a href="https://kumojin.com/"&gt;Kumojin&lt;/a&gt; team who waited patiently for me to be able to move to Canada for more than 8 months.&lt;/p&gt;

&lt;p&gt;Kudos to Faustine and Pierre who took the time to explain NgRx to me. &lt;/p&gt;

</description>
      <category>angular</category>
      <category>redux</category>
      <category>webdev</category>
      <category>ngrx</category>
    </item>
    <item>
      <title>Being a CTO is great, but ...</title>
      <dc:creator>Matthew</dc:creator>
      <pubDate>Sun, 04 Aug 2019 13:12:34 +0000</pubDate>
      <link>https://dev.to/hahnmatthieu/being-a-cto-is-great-but-2kl9</link>
      <guid>https://dev.to/hahnmatthieu/being-a-cto-is-great-but-2kl9</guid>
      <description>&lt;p&gt;Earlier this week I wrote my first blog post, and, to be honest, I was so surprised to see how many people reacted to it here and on Twitter. I've no idea if the numbers are good or not and I don't really care. &lt;br&gt;
I just want to thank you all for reading and leaving replies which I'm sure will help me write my next blog posts.&lt;/p&gt;

&lt;p&gt;In my last post I explained how I became CTO, but I didn't go through what I love with this job and what makes me think I maybe should have waited or tried something else before.&lt;/p&gt;

&lt;h1&gt;
  
  
  Being a CTO
&lt;/h1&gt;

&lt;p&gt;First of all, I want you to know that what I'm sharing here is my experience of the job and it's probably not what another CTO would think or tell you. What I think is cool or uncool about this job is my perception but, hey, isn't it the aim of all this ?&lt;/p&gt;

&lt;p&gt;The company that I work for only has a few developers and half of them are outsourced. This was already the case when I arrived two years ago. So, I'm not the CTO of the next Uber, Twitter or whatever, and that's fine by me.&lt;/p&gt;

&lt;h2&gt;
  
  
  The good parts of the job
&lt;/h2&gt;

&lt;p&gt;Being a CTO is awesome in many aspects:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I love building things, and, being a CTO means you're taking decisions with the CEO to build the company the way you want it to go and it's soooo interesting !&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I get to choose what tools we'll be using for the next few years. Of course, I don't choose on my own, but I have a big responsibility in the choice. What I like the most about that, is building the Proofs Of Concept and getting to explain the pros and cons of a solution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I work with a small team of developers that all have their ideas on what we should do next, why we are doing things wrong, how they would do them better and being in the center of this is overwhelming in a good way.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I'm in charge of recruiting the team that will build our products. I'll put this item in both cool and uncool lists and explain why it's also uncool to me. Recruiting is fun ! You get to meet people that come from different backgrounds. When I'm recruiting a Junior dev who has just finished her/his course, I often speak about what I'm learning right now and see what they understand about the subject (and I don't expect them to know anything about it). I'll always give them hints on books I have read or websites I have visited and that helped me a lot. When I'm recruiting a more experienced dev, I often do the opposite and ask what they learned last and try to understand the stuff myself.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The downfalls
&lt;/h2&gt;

&lt;p&gt;Well, not everything is perfect (For myself of course) :-P&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For some of the next few items, I have to say, my CEO is a control freak. She needs to have a grasp on every single feature even though she doesn't always get the idea.&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Recruiting: Of course, you can't recruit everyone, so you have to say no to great people and I hate that. On a totally different aspect, it also consumes a lot of my time. The other hard part is having to battle with my CEO on why someone who hasn't got a freaking computer science degree should be hired rather than someone who has. God! It's hard !&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Working with an outsourced team (considering my CEO): You got the idea. Just imagine a feature that was estimated to 10 days of work and finally takes 12 or 13 maybe. Then I need to explain once again, that writing code isn't an exact science. It's like making a cake. Ask me to follow the recipe that should take 15 minutes, I'll take me at least an hour. Ask my wife ? She'll have it finished in 10 minutes. Even though I know how to cook, my wife is much better at it than I am, it's a fact. In my opinion, coding is pretty much the same.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Planning: I hate planning for other people ! I already hate doing it for myself. That's one of the main reason I thought I wasn't made for project management. I love mentoring, I love explaining what I've built, but I freaking hate planning.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Well, I don't write as much code as I'd like too. This is one of the hardest aspects. I really love building stuff and I only get little time to do it. Most of the time I think: "Oh I'd love to build this feature!" and then "Man, I don't have time for this, let's hand it out to our outsourced team". So all I get to do is write on how I think the feature should be built.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  What if ?
&lt;/h1&gt;

&lt;p&gt;What If had to start my career all over again today ?&lt;/p&gt;

&lt;p&gt;Honestly, I don't think I'd go for the CTO stuff. Don't get me wrong, put aside the hard relation with my CEO, I like it a lot. But I, by far, prefer building stuff, and I really don't do enough of it today.&lt;/p&gt;

&lt;p&gt;I've done a little freelancing this year and that's something I find awesome. You can change stacks all the time, you're forced (in the good way) to stay up to date with tech and you're pretty much free to choose your "boss". &lt;/p&gt;

&lt;p&gt;When I speak to young developers who have just finished school, the question I often ask them: "Why don't you try freelancing ?".&lt;/p&gt;

&lt;p&gt;The answer is pretty much the one I would have given too: &lt;strong&gt;"I don't feel legitimate enough"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So, I think, we, as a community, should help those young developers to feel more legitimate.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Any idea on how we could do that ? Feel free to respond to this post, I'd be glad to discuss it with you all.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>webdev</category>
      <category>career</category>
    </item>
    <item>
      <title>How I became CTO in just a few years</title>
      <dc:creator>Matthew</dc:creator>
      <pubDate>Fri, 02 Aug 2019 07:36:00 +0000</pubDate>
      <link>https://dev.to/hahnmatthieu/how-i-became-cto-in-just-a-few-years-464a</link>
      <guid>https://dev.to/hahnmatthieu/how-i-became-cto-in-just-a-few-years-464a</guid>
      <description>&lt;p&gt;I'm not sure how to start about this, so let's go with the beginning.&lt;/p&gt;

&lt;p&gt;I've been in the webdev industry for just a few years and am the CTO of a small french e-health company that provides programs for people who suffer from weight, insomnia  or stress issues. And that feels great, believe me !&lt;/p&gt;

&lt;p&gt;So you might be asking yourself where I'm going with this ...&lt;/p&gt;

&lt;h1&gt;
  
  
  At the very beginning
&lt;/h1&gt;

&lt;p&gt;The thing is, this wasn't quite the career I was aiming at when I started college and then graduated. I did start with a computer science two year course where I learnt the basis of algorithms and how to code in C, C++ and other cool stuff like that, but the teachers, at the time, kept telling us that being a developper was like being a the bottom of the food chain.&lt;/p&gt;

&lt;p&gt;Clearly, according to them, the trend was to be on the functional side of tech. So I went on with a masters degree to become project manager. Therefore, I started my career by writing functional specifications (Gasp).&lt;/p&gt;

&lt;h1&gt;
  
  
  The turning point
&lt;/h1&gt;

&lt;p&gt;I was working for this big power company writing specs on data exchange between the different apps and noticed we had no way to know where the data really was. So I developed a small Java JSX app that enabled us to track the data, it worked so well, they put it into production, I was thrilled !&lt;/p&gt;

&lt;p&gt;I thought, what the hell am I doing writing functional specs and wanting to be project manager, I hate all of that! At this point, I was regretting all I had done until then, thinking that I would never be fully happy with my career, ever.&lt;/p&gt;

&lt;p&gt;This company then started to replace their awful palm devices by iPads and were looking for developers to build the new apps. So they hired this guy to start working on the stuff and I dared to ask if I could have a try on working with him, and if he would mentor me. This is the best decision I have ever made in my whole career!&lt;/p&gt;

&lt;p&gt;They accepted ! They gave me the chance I needed. Up to me to make it worth it.&lt;/p&gt;

&lt;p&gt;I worked 2 years there was great to learn, but the thing with big companies is that you never really get to see the whole picture. You just work on a part of a project. So I left, to work as a Lead Fullstack developer in a Startup for 1 year and then had the opportunity to become CTO of another small company.&lt;/p&gt;

&lt;p&gt;I decided to give it a try, even though I didn't really feel legitimate for the job. I felt like I was missing so much knowledge and that I would never manage to take the right decisions fast enough.&lt;/p&gt;

&lt;h1&gt;
  
  
  To the point now
&lt;/h1&gt;

&lt;p&gt;A few points I'd like tech recruiters to not forget:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Studies are a good thing, but they don't make you a good developer, passion and practicing does.&lt;/li&gt;
&lt;li&gt;Junior developers can be really good if you just give them a chance, we all were Junior first&lt;/li&gt;
&lt;li&gt;It really is possible to learn how to code in just as few weeks (this one is for my CEO who thinks it's better not to hire people who don't have a computing background)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the first blog post I've ever written, and it feels right. I didn't want to start with some technical stuff. I really wanted to thank some people I follow on twitter for making me feel legitimate to write here.&lt;/p&gt;

&lt;p&gt;So thank you &lt;/p&gt;
&lt;div class="ltag__user ltag__user__id__"&gt;
    &lt;div class="ltag__user__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F99mvlsfu5tfj9m7ku25d.png" alt="[deleted user] image"&gt;
    &lt;/div&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;[Deleted User]&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
 &lt;div class="ltag__user ltag__user__id__38627"&gt;
    &lt;a href="/aspittel" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&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%2Fuser%2Fprofile_image%2F38627%2F77a2a5e7-603e-41b4-afcc-f7aff468ae2f.jpg" alt="aspittel image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/aspittel"&gt;Ali Spittel&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/aspittel"&gt;Passionate about education, Python, JavaScript, and code art.&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
 &lt;div class="ltag__user ltag__user__id__1"&gt;
    &lt;a href="/ben" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&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%2Fuser%2Fprofile_image%2F1%2Ff451a206-11c8-4e3d-8936-143d0a7e65bb.png" alt="ben image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/ben"&gt;Ben Halpern&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/ben"&gt;A Canadian software developer who thinks he’s funny.&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;and all the others for making this happen.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>webdev</category>
      <category>career</category>
    </item>
  </channel>
</rss>
