'Property 'title' does not exist on type '{}'
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();
}
}
Solution 1:[1]
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>
Solution 2:[2]
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)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Supun De Silva |
| Solution 2 | Nimantha |
