Friday, March 9, 2018

Switching from Template Driven, to Reactive or Model Driven Forms

When we started writing Angular 2 apps, we had come from an AngularJS background. So of course our first forms were template driven. All we had to change from AngularJS was ng-model to ngModel and put it in a banana box. As long as the form's validation remains simple, Template driven forms are probably the way to go primarily due to their simplicity. However as the complexity of the forms grows, especially the validation of the form, its readability and even feasibility go bad pretty quickly. The only other downside to template driven forms is that they can't be unit tested. In our company most of these sorts of things were tested at an end-to-end level using Gherkin anyway, so less of an issue for us. But again as the complexity grows you might need to start unit testing those edge cases.

So let's take a relatively straightforward concrete example where the validation requirements might force us into implementing them in Reactive or Model-Driven forms. One side note about the nomenclature, we try to use Model Driven in our company, because we have React projects as well, and things can get pretty confusing distinguishing between a React form and a Reactive form. The example we are going to look at is a change password form. The validation requirements are that the passwords are strong, and that they match.

First let's take a look at the Template Driven HTML (change-password.component.html)

Change Password

{{error}}

And here is the TypeScript (change-password.component.ts)

export class ChangePasswordComponent {
  formErrors: string[];

  oldPassword: string;
  newPassword: string;
  confirmNewPassword: string;

  constructor() { }

  changePassword() {
    // submit to server
    if (this.newPassword!==this.confirmNewPassword){
      this.formErrors=["Passwords don't match"];
    } else {
      this.formErrors=[];
    }
  }
}

So far no validation. It *is* possible to write template validation using directives, but it is much simpler using Model-driven forms. To convert over the first thing we need to remember is to add the ReactiveFormsModule to your module (app.module.ts)

import { FormsModule, ReactiveFormsModule } from '@angular/forms';
and
imports:[
 BrowserModule, FormsModule, ReactiveFormsModule

Then at the top of your component (change-password.component.ts) you will need to add:

import { FormBuilder, FormGroup } from '@angular/forms';

In the fields section of your component replace

  oldPassword: string;
  newPassword: string;
  confirmNewPassword: string;
with
  form: FormGroup;

Lastly, change the constructor to this:

constructor (protected formBuilder: FormBuilder) {
  this.form=formBuilder.group({
    oldPassword:[''],
    newPassword:[''],
    confirmNewPassword:['']
  });
}

So basically there is one field where there use to be three, but the constructor was expanded to initialize the form with those three values. Now let's change the HTML (change-password.component.html). First find the form element, and change

  
to
  

Lastly, change all banana in a boxed ngModels, e.g. [(ngModel)] to formControlName. Here is an example change:

        
to
        

After doing that for all 3 fields. Voila! it is converted.

In Part 2 I will talk about the validation.

PS: For some reason Blogger and/or SyntaxHighlighter hate Angular code, it might be easier to read this over on my BrainHz blog

Wednesday, March 7, 2018

Power BI Tip: How to stay logged in to multiple powerbi.com accounts at the same time.

I have a great tip today!

 As a consultant, I find it difficult to switch between accounts on PowerBI.com.

 I have to log out of an existing account and log back in to a new account. The login process takes a long time. I have found a work around. I use google chrome to manage different chrome accounts, different themes, different cookies, and this allows me to stay logged in to multiple power bi accounts at the same time.

 1. In Chrome, click the title bar on the upper-right corner of the screen.

 You'll see your name, probably:

 

 2. Click on your name and pull down the menu. Click Manage People.

 3. Add different names for each of the Power BI accounts that you manage. I start mine with "Client - " and the name of the company, just so they're all grouped together.

 Now, each time you click on a profile, you will open a new chrome window. That profile will have different cookies, settings, bookmarks, and themes. I use themes to tell them all apart from each other. I use bookmarks to keep VPN logins, JIRA boards, TFS, and Azure logins all separate from one another.

 Here, I made a video on this for you:



 Hope this helps you!

 Ike