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);