Getting Stated with Angular Reactive Forms

It is time for another deep dive into Angular dear reader. In this article we are going to look at Angular’s Reactive Forms library under the hood, to see how it models forms and GUI elements.

I thought I would take a slightly different approach and poke around in the Angular source code to try to understand how the form controls and directives work, as there are plenty of tutorials on Reactive forms already available online, including the excellent tutorial in the Angular docs.

Let’s start by looking at the @angular/forms library on github.com. Open it up now or you won’t be able to follow along and make the most of this guide.

What exactly are Reactive forms?

If you take a look in the Angular 8 source code, you will find a directory for @angular/forms in the packages/forms/src folder. In order to understand the awesomeness of Reactive forms we will have to put on our detective glasses and look for clues as to how the library works.

A Reactive Form is a fancy way for saying a model driven form, which has been designed using the principles of functional reactive programming. Angular’s Reactive Forms library provides a series of classes, components and directives that use Observables under the hood to provide a way of manipulating forms in a more Reactive style.

A more simple approach to forms is to use the Template driven forms. Template driven forms are designed for very simple use cases. Template driven forms are more lightweight and easy to use, but lack a lot of the power of Reactive Forms.

// Example Template driven form using ngForm and ngModel
<form (ngSubmit)="onSubmit()" #heroForm="ngForm">
<div class="form-group">   
<input [(ngModel)]="currentHero.name">

You can add attributes like [ngForm](https://angular.io/api/forms/NgForm) and ngModelto your html inputs and Angular’s magic directives will automatically utilise two-way binding to make the form data available to your code. Changes to currentHero.name in your code will be automatically reflected in the view, and your code will always have the latest value of the form component.

One-way or Two-way binding…

As a brief aside on the subject of binding, did you know that you can actually work out which type of binding Angular is using by looking at how the property attributes are structured?

// One-way binding from data source to view target
[target]="expression" 
bind-target="expression"

// One-way binding from view target to data source (i.e. events)(target)="statement" 
on-target="statement"

// Two-way binding 
[(target)]="expression" 
bindon-target="expression"

To see if something has two-way binding, look for a bannana in a box! e.g. [(ngModel)] Both have their uses. Two-way binding is simple and easy to use, but one-way binding tends to be easier to reason with in larger applications, has fewer side effects and scales more easily. Facebook’s React library doesn’t support two-way binding for a reason!

Template Driven vs Reactive…

Whilst at first glance template forms seem handy, they offer some issues when scaling up an application. Firstly, it requires some processor and memory resources to keep track of each control. If you have lots of controls in your app then this is going to end up slowing down your application.

The second issue is that the two-way bound data is mutable, which essentially means that you cannot guarantee that the data isn’t going to be changed whilst you are working with it. We will never be sure if what we can see is accurate or if it will be changed whilst we are working with the data due to the asynchronous nature of the two-way binding. Template driven forms also only support form validation via directives and not functions, making them less flexible.

Reactive forms on the other hand don’t have this problem, they are synchronous, immutable, support structured data models, validation via functions and low-level control of all form components.

In Angular there are three key building blocks for defining forms:

  • FormGroup
  • FormControl
  • FormArray

All of which are used by both Reactive and the Template driven forms.

AbstractControl

AbstractControl is defined in models.ts and is the base class for FormControl, FormGroup and FormArray. Angular docs provide some more information:

  • It provides some of the shared behavior that all controls and groups of controls have, like running validators, calculating status, and resetting state. It also defines the properties that are shared between all sub-classes, like value, valid, and dirty. It shouldn’t be instantiated directly.

The AbstractControl class is quite large, so we will take a look through it to see the interesting bits. Here is the parent() method:

get parent(): FormGroup|FormArray { return this._parent; }

Cool, we now know that any AbstractControl potentially has a parent which is either a FormGroup or FormArray. This also means that both FormGroup’s and FormArray’s can be nested. FormControl’s however cannot, which makes sense.

Next up we have the status of the control, which is a simple string showing the validation status:

  • VALID: This control has passed all validation checks.
  • INVALID: This control has failed at least one validation check.
  • PENDING: This control is in the midst of conducting a validation check.
  • DISABLED: This control is exempt from validation checks.

This property allows any child classes of AbstractControl to easily check the validation status:

get valid(): boolean { return this.status === VALID; }
get invalid(): boolean { return this.status === INVALID; }

There is a pristine property too, which lets us know if the user has yet to change the value of the control. A control changed by a filthy human will also become dirty, which we can check with dirty().

public readonly pristine: boolean = true;
get dirty(): boolean { return !this.pristine; }

Similarly, we also have a touched property, which is if the user has triggered the blur event on it.

public readonly touched: boolean = false;

Now this is where it gets interesting, we have an Observable property called valueChanges that emits events every time the value of the control changes in the UI or programatically.

public readonly valueChanges : Observable<any>;

We also have another observable that emits statusChanges:

public readonly statusChanges : Observable<any>;

updateOn() returns the formHook that this control is currently set to update on. This allows the developer to specify when the control should update it’s parent FormArray or FormGroup that it’s value has been changed. By default, the control will update it’s parent form each time the control is changed, but we might prefer it to update on blur, when the user exits the control, or only when the final submit button is pressed. Possible values for _updateOn are: change (default) | blur | submit

get updateOn(): FormHooks {    
  return this._updateOn ? this._updateOn : (this.parent ? this.parent.updateOn : 'change');  
}

**setValue()**allows the developer to set the value of the control which seems straight forward and reset() resets the control. patchValue() however enables the developer to patch the value of the control. Huh?

abstract setValue(value: any, options?: Object): void;
abstract reset(value?: any, options?: Object): void;
abstract patchValue(value: any, options?: Object): void;

Well it turns out that both patchValue and setValue can be used to change the control’s value. Sami C. explains the difference simply in his medium article setValue vs patchValue, and Todd Motto dives deep into the API far better than I can in his tutorial, but the gist is this:

patchValue() allows us to selectively set the value of some controls in a FormGroup or FormArray. setValue requires that all of the controls are set.

Finally, update**ValueAndValidity()** can be used to recalculate the value and validation status. It will also update the value of it’s ancestors by default in the event that some higher up logic might dictate if the whole form is valid.

updateValueAndValidity(
  opts: {
    onlySelf?: boolean, 
    emitEvent?: boolean
  } = {}): void {      this._setInitialStatus();    
  this._updateValue();    // If the control is enabled  
  if (this.enabled) {    // Calls unsubscribe on any asyncValidation Subscriptions      
    this._cancelExistingSubscription();
   
   // runs the validator and assigns any errors to this.errors 
   (this as{errors: ValidationErrors | null}).errors = this._runValidator();    // Update's the control's current status (post validation check)
    (this as{status: string}).status = this._calculateStatus();            // If the control is valid or still pending, it runs the asynchronous validation checks
    if (this.status === VALID || this.status === PENDING) {        
      this._runAsyncValidator(opts.emitEvent);      }    
    }     
    
    // Emit the new value and status as events
    if (opts.emitEvent !== false) {      
       (this.valueChanges as EventEmitter<any>).emit(this.value);        
       (this.statusChanges as EventEmitter<string>).emit(this.status);    
    }    // If the control has a FormArray or FormGroup parent, call its validation function
   if (this._parent && !opts.onlySelf) {        
      this._parent.updateValueAndValidity(opts);    
    }
}

We have learned so far that this AbstractControl class is quite important as it provides some of the default behaviour and properties for any FormControl, FormGroup or FormArray, all of which extend AbstractControl. We have skipped over validation for now, but we should get a sense that the same methods and properties are shared across these three important classes and whilst their implementations might differ, they all have this uniform interface thanks to AbstractControl.

AbstractControl also has an interface called AbstractControlOptions that provides more specific configuration data for the AbstractControl. This can be passed into any FormControl, FormGroup or FormArray constructor to define specific validators and updateOn parameters.

export interface AbstractControlOptions {  
    // The list of validators applied to a control.
    validators?: ValidatorFn|ValidatorFn[]|null;
    
    // The list of async validators applied to control.
    asyncValidators?: AsyncValidatorFn|AsyncValidatorFn[]|null;
    
    // The event name for control to update upon.
    updateOn?: 'change'|'blur'|'submit';
}

You might have also noticed that there is no reference to the DOM in any of the above. This is because AbstractControl, FormControl,FormGroup and FormArray are all models, or ‘virtual_’_ form components — hence why they are found in models.ts. By abstracting forms and controls and away from the DOM, we can start to add some useful functionality such as validators and provide more fine grained control over the form. Angular Directives will eventually take care of joining our models with our DOM components, as we will see later.

FormControl

FormControl is our virtual model of our Form component. It’s main job is to track the validation status of an individual form control, and it gets most of it’s basic functionality by extending AbstractControl. We can use a FormControl in a few different ways by passing a value for the control, and optionally we can also pass an options configuration object for more fine grained control:

const control = new FormControl('some value'); console.log(control.value);     // 'some value'

const control = new FormControl({ value: 'n/a', disabled: true }); 
console.log(control.value);     // 'n/a' console.log(control.status);    // 'DISABLED'const control = new FormControl('', { 
  updateOn: 'blur',
  validators: Validators.required, 
  asyncValidators: myAsyncValidator 
});

Let’s take a look at the constructor:

// FormControl constructor
onstructor(  // The form state or value      
  formState: any = null,        // A synchronous validator or Options object
  validatorOrOpts?: ValidatorFn|ValidatorFn[]|  AbstractControlOptions|null, 
     
  // An asynchronous validator
  asyncValidator?: AsyncValidatorFn|AsyncValidatorFn[]|null
) 
{      // Call AbstractComponent constructor with validators
  super(        
    coerceToValidator(validatorOrOpts),        
    coerceToAsyncValidator(asyncValidator, validatorOrOpts)
  );      // Apply the value by calling _applyFormState(formState)
  this._applyFormState(formState);
  
  // Pass in the options configuration obj and set update strategy     
  this._setUpdateStrategy(validatorOrOpts);
  
  // update the value and check the validity    
  this.updateValueAndValidity({onlySelf: true, emitEvent: false});    
  
  // Initialize our observables
  this._initObservables();  
}

formState Initializes the control with an initial value, or an object that defines the initial value and disabled state. The second parameter takes either a full AbstractControlOptions object or a synchronous validator, and the final property, asyncValidator, defines any asynchronous validators.

We can see that the formState parameter gets passed along to _this._applyFormState(formState)_, a private function of the FormControl.

// FormControl class in models.ts (Angular v8)
 private _applyFormState(formState: any) {
    if (this._isBoxedValue(formState)) {
      (this as{value: any}).value = this._pendingValue = formState.value;
      formState.disabled ? this.disable({onlySelf: true, emitEvent: false}) :
                           this.enable({onlySelf: true, emitEvent: false});
    } else {
      (this as{value: any}).value = this._pendingValue = formState;
    }
  }
}

_applyFormState() checks to see if formState is a simple or boxed value, i.e. an object like{value: 'test', disabled: 'false'} and then sets the this.value and this._pendingValue to the new formState.value.

Remember in AbstractControl we had a SetValue() function? Lets see how this is defined in the FormControl component. I have added comments to the lines below to explain what each is doing:

  //FormControl setValue
  setValue(value: any, options: {
    onlySelf?: boolean, // When true, each change only affects this control, and not its parent.
    emitEvent?: boolean, // When true or not supplied (the default),
    emitModelToViewChange?: boolean, //  When true or not supplied  (the default), each change triggers an `onChange` event
    emitViewToModelChange?: boolean // When true or not supplied (the default), each change triggers an `ngModelChange` event
  } = {}): void {
    // Update the value
    (this as{value: any}).value = this._pendingValue = value;
    
    // Notify others of the change if we are allowed to emit events
    if (this._onChange.length && options.emitModelToViewChange !== false) {

      // Loop through each of our onChange subscriber functions and call them to notify them of an update
      this._onChange.forEach(
          (changeFn) => changeFn(this.value, options.emitViewToModelChange !== false));
    }
    // update the form value and check it's validity, calling other validators if req.
    this.updateValueAndValidity(options);
  }
  
    /**
   * Patches the value of a control.
   * This function is functionally the same as setValue at this level.
   * It exists for symmetry with patchValue on `FormGroups` and `FormArrays`, where it does behave differently.
   */
  patchValue(value: any, options: {
    onlySelf?: boolean,
    emitEvent?: boolean,
    emitModelToViewChange?: boolean,
    emitViewToModelChange?: boolean
  } = {}): void {
    this.setValue(value, options);
  }

Cool, so it appears that we have an array of callback functions _onChange that we can notify when we update the form value. We also have an _onDisabledChangearray of callback functions for when we change the disabled state of the component. We can register callbacks with the registerOnChange() or registerOnDisabledChange() functions:

registerOnChange(fn: Function): void { this._onChange.push(fn); }
registerOnDisabledChange(fn: (isDisabled: boolean) => void): void {    this._onDisabledChange.push(fn);  }

patchValue() just calls setValue() on the FormControl component and is there for completeness.

Finally, we have a _syncPendingControls() function, that will update the control with the latest _pendingDirty, _pendingTouched, and _pendingValue values only in the case that updateOn === ‘submit’.

/** @internal */ 
_syncPendingControls(): boolean {    
  if (this.updateOn === 'submit') {      
    if (this._pendingDirty) this.markAsDirty();      
    if (this._pendingTouched) this.markAsTouched();      
    if (this._pendingChange) {        
      this.setValue(this._pendingValue, {onlySelf: true, 
      emitModelToViewChange: false});        
      return true;      
    }
  }
  return false;  
}

This allows the user to change the internal component values without officially updating it’s state. All such, values get temporarily assigned to a _pending variables and will only change the state of the component on demand when the _syncPendingControls() function is called, e.g. by a parent FormGroup or FormArray whose submit button has just been pressed.

FormGroup

FormGroup is our virtual model of our form and is defined in models.ts. The Angular docs explain what FormGroup does quite well:

A FormGroup aggregates the values of each child FormControl into one object, with each control name as the key. It calculates its status by reducing the status values of its children.

For example, if one of the controls in a group is invalid, the entire group becomes invalid. FormGroup is one of the three fundamental building blocks used to define forms in Angular, * along with FormControl and FormArray.

We can create a FormGroup instance as follows:

// Define a basic form group consisting of two controls
const form = new FormGroup({ 
   first: new FormControl('Nancy', Validators.minLength(2)), 
   last: new FormControl('Drew'), 
});// Include a group-level validator
const form2 = new FormGroup(
 { 
  password: new FormControl('', Validators.minLength(2)), 
  passwordConfirm: new FormControl('', Validators.minLength(2))
 },  
  passwordMatchValidator);

The FormGroup class is defined in model.ts:

// Creates a new `FormGroup` instance.
export class FormGroup extends AbstractControl {constructor(      
  //  A collection of child controls. 
  public controls: {[key: string]: AbstractControl},       
 
  //  A synchronous validator function, or an array of such func
  validatorOrOpts?:    
  ValidatorFn|ValidatorFn[]|AbstractControlOptions|null,// A single async validator or array of async validator functions
  asyncValidator?: AsyncValidatorFn|AsyncValidatorFn[]|null
){super(        
  coerceToValidator(validatorOrOpts),         
  coerceToAsyncValidator(asyncValidator, validatorOrOpts));this._initObservables();    this._setUpdateStrategy(validatorOrOpts);    
this._setUpControls();    
this.updateValueAndValidity({onlySelf: true, emitEvent: false});  
}// Other methods 
}

The FormGroup constructor takes a collection of child controls via the controls parameter, together with a synchronous or aynchronous validator function (or array). It then calls it’s parent class with the synchronous and asynchronous validators. Finally, the constructor initialises the Observables, sets up the update strategy and controls and then updates itself. Did you spot that the controls and the parent class of FormGroup is the AbstractControl class?

Conclusion

Angular’s forms library and models help us to create virtual forms that we can manipulate and subscribe to. The models share common interfaces and behaviour which makes working with the different components easier. This enables the Angular Reactive Form directives take our DOM elements and link them with our models so that any changes get updated in our components automatically.

Hopefully this article has helped to shine a light on how Form Groups and FormControl components are modelled internally by angular.

#Angular #WebDev #JavaScript

What is GEEK

Buddha Community

Getting Stated with Angular Reactive Forms

I am Developer

1608866530

Angular 11 Reactive Forms Validation Tutorial

Reactive form validation in Angular 11 app. In this tutorial, i will show you how to use reactive form validation in angular 11 app.

As well as, and you will learn how use reactive form validation in angular 11. And also use reactive form with formGroup for validation in angular 11 app.

Reactive Form Validation In Angular 11
Step 1 – Create New Angular App
Step 2 – Import Form Module
Step 3 – Add Code on View File
Step 4 – Use Component ts File
Step 5 – Start Angular App

https://www.tutsmake.com/angular-11-reactive-forms-validation-tutorial-example/

#reactive form validation in angular 11 #angular 11/10/9/8/7 reactive forms validation example #angular 11 form validation example

Christa  Stehr

Christa Stehr

1598940617

Install Angular - Angular Environment Setup Process

Angular is a TypeScript based framework that works in synchronization with HTML, CSS, and JavaScript. To work with angular, domain knowledge of these 3 is required.

  1. Installing Node.js and npm
  2. Installing Angular CLI
  3. Creating workspace
  4. Deploying your First App

In this article, you will get to know about the Angular Environment setup process. After reading this article, you will be able to install, setup, create, and launch your own application in Angular. So let’s start!!!

Angular environment setup

Install Angular in Easy Steps

For Installing Angular on your Machine, there are 2 prerequisites:

  • Node.js
  • npm Package Manager
Node.js

First you need to have Node.js installed as Angular require current, active LTS or maintenance LTS version of Node.js

Download and Install Node.js version suitable for your machine’s operating system.

Npm Package Manager

Angular, Angular CLI and Angular applications are dependent on npm packages. By installing Node.js, you have automatically installed the npm Package manager which will be the base for installing angular in your system. To check the presence of npm client and Angular version check of npm client, run this command:

  1. npm -v

Installing Angular CLI

  • Open Terminal/Command Prompt
  • To install Angular CLI, run the below command:
  1. npm install -g @angular/cli

installing angular CLI

· After executing the command, Angular CLI will get installed within some time. You can check it using the following command

  1. ng --version

Workspace Creation

Now as your Angular CLI is installed, you need to create a workspace to work upon your application. Methods for it are:

  • Using CLI
  • Using Visual Studio Code
1. Using CLI

To create a workspace:

  • Navigate to the desired directory where you want to create your workspace using cd command in the Terminal/Command prompt
  • Then in the directory write this command on your terminal and provide the name of the app which you want to create. In my case I have mentioned DataFlair:
  1. Ng new YourAppName

create angular workspace

  • After running this command, it will prompt you to select from various options about the CSS and other functionalities.

angular CSS options

  • To leave everything to default, simply press the Enter or the Return key.

angular setup

#angular tutorials #angular cli install #angular environment setup #angular version check #download angular #install angular #install angular cli

Clara  Gutmann

Clara Gutmann

1598705160

Angular 8 Forms | Angular Reactive and Template Forms

Angular Forms are used to handle the user’s input. We can use Angular form in our application to enable users to log in, update profiles, enter information, and to perform many other data-entry tasks.

If you are new to Angular, then check out myAngular Tutorial. If you do not know how to upgrade to Angular 8 via Angular CLI, then check out my Angular Upgrade tutorial. Managing user input with forms is the cornerstone of many web applications.

The web app uses forms to enable the users to log in, to update a profile, to enter sensitive information, and to perform many data-entry tasks.

#angular #angular 8 #angular reactive

Roberta  Ward

Roberta Ward

1595344320

Wondering how to upgrade your skills in the pandemic? Here's a simple way you can do it.

Corona Virus Pandemic has brought the world to a standstill.

Countries are on a major lockdown. Schools, colleges, theatres, gym, clubs, and all other public places are shut down, the country’s economy is suffering, human health is on stake, people are losing their jobs and nobody knows how worse it can get.

Since most of the places are on lockdown, and you are working from home or have enough time to nourish your skills, then you should use this time wisely! We always complain that we want some ‘time’ to learn and upgrade our knowledge but don’t get it due to our ‘busy schedules’. So, now is the time to make a ‘list of skills’ and learn and upgrade your skills at home!

And for the technology-loving people like us, Knoldus Techhub has already helped us a lot in doing it in a short span of time!

If you are still not aware of it, don’t worry as Georgia Byng has well said,

“No time is better than the present”

– Georgia Byng, a British children’s writer, illustrator, actress and film producer.

No matter if you are a developer (be it front-end or back-end) or a data scientisttester, or a DevOps person, or, a learner who has a keen interest in technology, Knoldus Techhub has brought it all for you under one common roof.

From technologies like Scala, spark, elastic-search to angular, go, machine learning, it has a total of 20 technologies with some recently added ones i.e. DAML, test automation, snowflake, and ionic.

How to upgrade your skills?

Every technology in Tech-hub has n number of templates. Once you click on any specific technology you’ll be able to see all the templates of that technology. Since these templates are downloadable, you need to provide your email to get the template downloadable link in your mail.

These templates helps you learn the practical implementation of a topic with so much of ease. Using these templates you can learn and kick-start your development in no time.

Apart from your learning, there are some out of the box templates, that can help provide the solution to your business problem that has all the basic dependencies/ implementations already plugged in. Tech hub names these templates as xlr8rs (pronounced as accelerators).

xlr8rs make your development real fast by just adding your core business logic to the template.

If you are looking for a template that’s not available, you can also request a template may be for learning or requesting for a solution to your business problem and tech-hub will connect with you to provide you the solution. Isn’t this helpful 🙂

Confused with which technology to start with?

To keep you updated, the Knoldus tech hub provides you with the information on the most trending technology and the most downloaded templates at present. This you’ll be informed and learn the one that’s most trending.

Since we believe:

“There’s always a scope of improvement“

If you still feel like it isn’t helping you in learning and development, you can provide your feedback in the feedback section in the bottom right corner of the website.

#ai #akka #akka-http #akka-streams #amazon ec2 #angular 6 #angular 9 #angular material #apache flink #apache kafka #apache spark #api testing #artificial intelligence #aws #aws services #big data and fast data #blockchain #css #daml #devops #elasticsearch #flink #functional programming #future #grpc #html #hybrid application development #ionic framework #java #java11 #kubernetes #lagom #microservices #ml # ai and data engineering #mlflow #mlops #mobile development #mongodb #non-blocking #nosql #play #play 2.4.x #play framework #python #react #reactive application #reactive architecture #reactive programming #rust #scala #scalatest #slick #software #spark #spring boot #sql #streaming #tech blogs #testing #user interface (ui) #web #web application #web designing #angular #coronavirus #daml #development #devops #elasticsearch #golang #ionic #java #kafka #knoldus #lagom #learn #machine learning #ml #pandemic #play framework #scala #skills #snowflake #spark streaming #techhub #technology #test automation #time management #upgrade

Angular Form Generator & Pitfalls

Ever felt repetitive creating forms in your Angular Application? Let’s fix it.

Intro

During the Front-end development days it feels like there is a lot of repetitive code which I have to write to design my forms which are almost all the time very close one to another.

I’ve been recently looking into ways of automating it. The furthest I wanted to go was to have some kind of interface between a more friendly modelling object as well as to an interface to link my objects to the Angular Modelling Universe.

This way, I discovered there is already a library that could do it for me formly. But looking over their documentation I realized this is a little bit more than I wanted.

As a result, I ended writing my own form generator. You’ll see that except for two or three pitfalls this is rather easy to achieve.

Foreground

I’ll be using Angular Materials to generate my forms.

I have two tips to share about their design. It can be difficult to change the colors or design a theme for them. You’ll see the documentation on their side is rather not the best on this subject. My piece of advice, use  https://materialtheme.arcsine.dev/. In case you don’t know exactly what colors to use but you have a slight idea about it, I recommend using  https://www.cssportal.com/css-color-converter/0000D8. In the end you’ll definitely discover some very cool Angular Material Theme which you can even share with others.

Getting Started

First of all, we’ll organize our application on modules. When it comes to Angular I always split the code in presentation and business. From where I’m standing, presentation means those components that deal with UX functionality, they can work by themselves but they don’t make sense for a user taken alone; business are those components that configure and group together presentation through a context.

#angular-forms #angular #typescript #angular-formly