Ошибка в том, что значение не инициализируется при запуске.Это происходит, когда переменная получает свое первое значение из подписки, что требует некоторого времени для получения значения, поэтому представление визуализируется и пытается получить значение до того, как оно существует.Я бы рекомендовал сначала создать модель для ваших данных, а затем инициализировать вашу модель. Посмотрите на Создание классов моделей в машинописи о том, как создать модель.Вы можете инициализировать его при запуске, чтобы избежать ошибки, или создать другую переменную, которая заставляет представление ждать переменную.
import { Component, OnInit, OnDestroy } from '@angular/core';
import { CategoryService } from 'src/app/category.service';
import { ProductService } from 'src/app/product.service';
import { Router, ActivatedRoute } from '@angular/router';
import { take } from 'rxjs/operators';
@Component({
selector: 'app-product-form',
templateUrl: './product-form.component.html',
styleUrls: ['./product-form.component.css']
})
export class ProductFormComponent implements OnInit {
categories$;
product;
initialized : boolean = false
constructor(
categoryService: CategoryService,
private route: ActivatedRoute,
private productService: ProductService,
private router: Router) {
this.categories$ = categoryService.getCategories();
let id = this.route.snapshot.paramMap.get('id');
if (id) this.productService.get(id).snapshotChanges().pipe(take(1))
.subscribe(p => {
this.initialized = true
this.product = p
});}
save(product) {
this.productService.create(product);
this.router.navigate(["/admin/products"]);
}
ngOnInit() {
}
}
Тогда HTML будет выглядеть так:
<div class="form-group">
<label for="title">Title</label>
<input #title="ngModel" *ngIf="initialized" [(ngModel)]="product.title"
name="title" id="title" type="text" class="form-control" required>
<div class="alert alert-danger" *ngIf="title.touched && title.invalid">
Title is required
</div>
</div>
Вы можете поиграться с переменной, чтобы создать индикатор загрузки по своему вкусу