Reputation: 105
Angular
In the first few tags I have an input tag input #title = "ngModel" [(ngModel)]="product.title" this code where I am trying to use two way binding to be able to edit my form and values that I get from the firebase database. I created an empty product object in product-form.component.ts but I get the property type error. I am not sure why the empty product object causing error because the tutorial I'm watching has the same approach. Goal is to be able to use that empty product object or an alternate approach to be able to work with two way binding
product-form.component.ts
import { ProductService } from './../../product.service';
import { CategoryService } from './../../category.service';
import { Component, OnInit } from '@angular/core';
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 = {};
constructor(
private route: ActivatedRoute,
private router: Router,
private categoryService: CategoryService,
private productService: ProductService)
{
this.categories$ = categoryService.getCategories();
let id = this.route.snapshot.paramMap.get('id');
if (id) this.productService.get(id).pipe(take(1)).subscribe(p => this.product = p);
}
save(product){
this.productService.create(product);
this.router.navigate(['/admin/products']);
}
ngOnInit(): void {
}
}
product-form.html
<div class="row">
<div class="col-md-6">
<form #f = "ngForm" (ngSubmit) = "save(f.value)">
<div class="form-group">
<label for="title">Title</label>
<input #title = "ngModel" [(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>
<div class="form-group">
<label for="price">Price</label>
<div class="input-group">
<span class="input-group-text">$</span>
<input #price="ngModel" ngModel name ="price" id = "price" type="number" class="form-control" required>
</div>
<div class="alert alert-danger" *ngIf="price.touched && price.invalid">
<div *ngIf="price.errors.required">Price is required.</div>
<div *ngIf="price.errors.min">Price should be 0.</div>
</div>
</div>
<div class="form-group">
<label for="category">Category</label>
<select #category="ngModel" ngModel name="category" id = "category" type="text" class="form-control" required>
<option value=""></option>
<option *ngFor = "let c of categories$ | async" [value] = "c.name">
{{c.name}}
</option>
</select>
<div class="alert alert-danger" *ngIf = "category.touched && category.invalid">
Category is required.
</div>
</div>
<div class="form-group">
<label for="imageUrl">Image Url</label>
<input #imageUrl="ngModel" ngModel name= "imageUrl" id = "imageUrl" type="url" class="form-control" required>
<div class="alert alert-danger" *ngIf = "imageUrl.touched && imageUrl.invalid">
<div *ngIf = "imageUrl.errors.required">Image URL is required.</div>
<div *ngIf = "imageUrl.errors.url">Invalid URL</div>
</div>
</div>
<button class="btn btn-primary">Save</button>
</form>
</div>
<div class="col-md-6">
<div class="card" style="width: 18rem;">
<img [src]="imageUrl.value" class="card-img-top">
<div class="card-body">
<h5 class="card-title">{{title.value}}</h5>
<p class="card-text">{{price.value | currency:'USD':true}}</p>
</div>
</div>
</div>
</div>
product.service.ts
import { Injectable } from '@angular/core';
import { AngularFireDatabase } from '@angular/fire/database';
@Injectable({
providedIn: 'root'
})
export class ProductService {
constructor(private db: AngularFireDatabase) { }
create(product){
return this.db.list('/products').push(product);
// const itemsRef = this.db.list('products');
// return itemsRef.push(product);
}
getAll() {
return this.db.list('/products').valueChanges();
}
get(productId){
return this.db.object('/products/' + productId).valueChanges();
}
}
Upvotes: 1
Views: 5892
Reputation: 53
I fixed this error by changing a couple of things in 'tsconfig.json' file.
First remove "strict":true
and add instead of it "noImplicitUseStrict":true
(Don't forget adding the comma)
Upvotes: 0
Reputation: 1487
There are 2 ways to do this
Approach 1
Declare an interface
export interface Product {
title: string
}
Change the Component code section as follows
from
product = {};
To
product:Product;
Approach 2 - This can have side effects
Change HTML
From
<input #title = "ngModel" [(ngModel)]="product.title" name = "title" id = "title" type="text" class="form-control" required>
To
<input #title = "ngModel" [(ngModel)]="product['title']" name = "title" id = "title" type="text" class="form-control" required>
Upvotes: 3