Reactive Forms correctly convert Form Value to Model Object
While creating a Model Driven Template Reactive forms, when I create model object from Form Value. Then model object is loosing its TYPE.
For a Simple Example:
Model Class Book:
export class Book {
public name: string;
public isbn: string;
}
Component:
@Component({
selector: 'app-book',
templateUrl: './book.component.html',
styleUrls: ['./book.component.css']
})
export class BookComponent implements OnInit {
bookFormGroup: FormGroup;
private newBook: Book = new Book();
constructor(private fb: FormBuilder) {
this.bookFormGroup = this.fb.group({
name: new FormControl(''),
isbn: new FormControl('')
});
}
ngOnInit() {
}
addBook() {
console.log('submit');
this.newBook = <Book> this.bookFormGroup.value;
console.log(this.newBook instanceof Book);
console.log(this.newBook);
}
}
HTML:
<form [formGroup]="bookFormGroup" (ngSubmit)="addBook()">
<input type="text" formControlName="name" >
<input type="text" formControlName="isbn" >
<input type="submit" value="Submit">
</form>
In the above example, after filling newBook
instance its converted to normal Object
i.e,
After this.newBook = <Book> this.bookFormGroup.value;
this.newBook instanceof Book
is becoming FALSE
How do I prevent this? Or is there any better way to achieve this?
Note: I tried with JSON.parse()
but it still same.
This constructor will work with any type and will assign any matching filed.
export class Book {
public constructor(init?: Partial<Book>) {
Object.assign(this, init);
}
}
So you will be able to do this:
this.newBook = new Book(this.bookFormGroup.value);
This will save you a lot of work if the Book class will have any change in future and became bigger.
I use spread operator:
this.newBook = {...this.newBook,...this.bookFormGroup.value}
Let's say your model is like this:
export class Content {
ID: number;
Title: string;
Summary: string;
}
Your component will look like this:
export class ContentComponent implements OnInit {
content: Content;
contentForm: FormGroup;
ngOnInit() {
this.contentForm = this.formBuilder.group({
Title: ['', Validators.required],
Summary: ['', Validators.required]
});.....
When the save button is called, you can merge the form builder object and the dto you have:
onContentFormSubmit() {
// stop here if form is invalid
if (this.contentForm.invalid) {
return;
}
this.content = Object.assign(this.content, this.contentForm.value);
}
this.content will have the predefined values you have from onInit and the values from the from group.
you can try this in your addBook()
:
let formData = Object.assign({});
formData = Object.assign(formData, this.bookFormGroup.value);
this.newBook = new Book(formData.name ,formData.isbn );
console.log(this.newBook instanceof Book);