Skip to content

Commit

Permalink
Merge pull request #2 from actionanand/features/1-template-driven
Browse files Browse the repository at this point in the history
Features/1 template driven
  • Loading branch information
actionanand authored Oct 1, 2024
2 parents b990237 + e50bded commit ed7b316
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 5 deletions.
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,3 +224,34 @@ To configure the pre-commit hook, simply add a `precommit` npm script. We want t
- [GitHub Actions for Angular](https://github.com/rodrigokamada/angular-github-actions)
- [Angular 16 - milestone release](https://github.com/actionanand/ng16-signal-milestone-release)
## Issue with `Template driven` form

If you try to update (say email value when app loads) template driven form programmatically using `setValue` on `NgForm`, it'll throw the error as below
![image](https://github.com/user-attachments/assets/6cbfe931-7b7e-4f19-892b-df7ad3b1e967)

We have to use `setTimeout` to fix the issue as below:

```ts
// to set value for whole form
setTimeout(() => {
this.formData().setValue({
email: 'anand@ar.com',
password: '',
});
}, 1);
```

If you try to update (say email value when app loads) template driven form programmatically using `setValue` on the `controls` of `NgForm`, it'll throw the error as below
![image](https://github.com/user-attachments/assets/b865d5cc-8fd6-4781-aacc-4989bd40b8dd)

We have to use `setTimeout` to fix the issue as below:

```ts
setTimeout(() => {
this.formData().controls['emailField'].setValue('anand@ar.com');
}, 1);
```

See the code in this project [here](https://github.com/actionanand/angular-form/blob/master/src/app/auth/login/login.component.ts)
27 changes: 24 additions & 3 deletions src/app/auth/login/login.component.html
Original file line number Diff line number Diff line change
@@ -1,17 +1,38 @@
<form>
<form #formEl="ngForm" (ngSubmit)="onSubmit(formEl)">
<h2>Login</h2>

<div class="control-row">
<div class="control no-margin">
<label for="email">Email</label>
<input id="email" type="email" />
<input id="email" type="email" name="emailField" ngModel required email #emailCtrl="ngModel" />
</div>

<div class="control no-margin">
<label for="password">Password</label>
<input id="password" type="password" />
<input
id="password"
type="password"
name="passField"
ngModel
required
[minlength]="minPassLength"
#passwordCtrl="ngModel" />
</div>

<button class="button">Login</button>
</div>

<!-- @if(formEl.form.invalid && formEl.form.controls['emailField'].touched) {
<p class="control-error">
Invalid email entered
</p>
} -->

@if (emailCtrl.touched && emailCtrl.dirty && emailCtrl.invalid) {
<p class="control-error">Invalid email address entered!</p>
}

@if (passwordCtrl.touched && passwordCtrl.dirty && passwordCtrl.invalid) {
<p class="control-error">Password must be atleast {{ minPassLength }} characters!</p>
}
</form>
58 changes: 56 additions & 2 deletions src/app/auth/login/login.component.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,63 @@
import { Component } from '@angular/core';
import { afterNextRender, Component, DestroyRef, inject, viewChild } from '@angular/core';
import { FormsModule, NgForm } from '@angular/forms';

import { debounceTime } from 'rxjs/operators';

@Component({
selector: 'app-login',
standalone: true,
imports: [FormsModule],
templateUrl: './login.component.html',
styleUrl: './login.component.css',
})
export class LoginComponent {}
export class LoginComponent {
minPassLength = 5;
private formObj = viewChild.required<NgForm>('formEl');
private destroyRef = inject(DestroyRef);

constructor() {
afterNextRender(() => {
const localFormVal = localStorage.getItem('saved-login-form');

if (localFormVal) {
const savedFormEmail = JSON.parse(localFormVal).email;

/* // to set value for whole form
setTimeout(() => {
this.formObj().setValue({
emailField: savedFormEmail,
passField: '',
});
}, 1); */

setTimeout(() => {
this.formObj().controls['emailField'].setValue(savedFormEmail);
}, 1);
}

const formSub = this.formObj()
.valueChanges?.pipe(debounceTime(1000))
.subscribe({
next: form => {
localStorage.setItem('saved-login-form', JSON.stringify({ email: form.emailField }));
},
});

this.destroyRef.onDestroy(() => formSub?.unsubscribe());
});
}

onSubmit(formEl: NgForm) {
if (formEl.form.invalid) {
return;
}

console.log(formEl);

console.log(formEl.form.controls['emailField']);
console.log(formEl.form.value['emailField']);

formEl.form.reset();
}
}
9 changes: 9 additions & 0 deletions src/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,12 @@ hr {
background-color: transparent;
color: #869999;
}

.control:has(.ng-invalid.ng-touched.ng-dirty) label {
color: #f98b75;
}

input.ng-invalid.ng-touched.ng-dirty {
background-color: #fbdcd6;
border-color: #f84e2c;
}

0 comments on commit ed7b316

Please sign in to comment.