错误TypeError:无法读取null的属性“ title”

时间:2019-11-17 07:28:53

标签: angular database firebase

我想通过以更新形式传递表值来更新Firebase(实时数据库)中的数据,但是它显示了一个错误=

  

ERROR TypeError:无法读取null的属性“ title”

并且每当我尝试使用[(ngModel)]="product.price"时,我的代码都会显示错误

  

无法读取null的属性“价格”

这是我的.ts文件

import { Component, OnInit } from '@angular/core';
import { CategoryService } from 'src/app/services/category.service';
import { ProductsService } from 'src/app/services/products.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 {

  product: any = {};
  categories$;
  constructor(
    private router: Router,
    private route: ActivatedRoute,
    private categoryService: CategoryService,
    private productService: ProductsService
  ) {
    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);
    console.log(product);
    this.router.navigate(['/admin/products']);
  }

  ngOnInit() {
  }

这是我的.html文件

<mat-grid-list cols="2" rowHeight="86%">
      <mat-grid-tile>
            <form class="example-form" #f="ngForm" (ngSubmit)="save(f.value)">
                  <mat-form-field class="example-full-width" appearance="outline">
                        <mat-label for="title">Product Name</mat-label>
                        <input matInput [(ngModel)]="product.title" name="title" type="text" id="title" required
                              #pname="ngModel">
                        <mat-error *ngIf="pname.touched"></mat-error>
                  </mat-form-field>
                  <mat-form-field class="mywidth" appearance="outline">
                        <mat-label for="price">Product Price</mat-label>
                        <input matInput ngModel name="price" type="number" id="price" #pprice="ngModel" required
                              [min]="0">
                        <mat-error style="color: red;" *ngIf="pprice.touched && pprice.invalid">field required*
                        </mat-error>
                        <span mat-button matSuffix mat-stroked-button aria-label="search">
                              <mat-icon>₹</mat-icon>
                        </span>
                  </mat-form-field>&nbsp;
                  <mat-radio-group ngModel name="subprice" #subprice="ngModel">
                        <mat-radio-button value="kg">/kg</mat-radio-button>&nbsp;
                        <mat-radio-button value="g">/g</mat-radio-button>&nbsp;
                        <mat-radio-button value="liter">/liter</mat-radio-button>
                  </mat-radio-group>
                  <mat-form-field class="example-full-width" appearance="outline">
                        <mat-label>Category</mat-label>
                        <mat-select ngModel name="category" id="category" required #cat="ngModel">
                              <mat-option>None</mat-option>
                              <mat-option *ngFor="let c of categories$ | async" [value]="c.name">{{ c.name }}
                              </mat-option>
                        </mat-select>
                        <mat-error style="color: red;" *ngIf="cat.touched && cat.invalid">field required*</mat-error>
                  </mat-form-field>
                  <mat-form-field class="example-full-width" appearance="outline">
                        <mat-label for="imageUrl">ImageUrl</mat-label>
                        <input matInput type="text" ngModel name="imageUrl" id="imageUrl" #imgUrl="ngModel">
                  </mat-form-field>
                  <button mat-raised-button type="submit" color="warn">Save</button>
            </form>
      </mat-grid-tile>
      <mat-grid-tile>
            <mat-card class="example-card">
                  <mat-card-header>
                        <mat-card-title>{{ pname.value }}</mat-card-title>
                  </mat-card-header>
                  <img mat-card-image [src]="imgUrl.value">
                  <mat-card-content>
                        <p>{{ pprice.value }} / {{ subprice.value }}</p>
                  </mat-card-content>
            </mat-card>

      </mat-grid-tile>
</mat-grid-list>

这是我的product.service.ts

 import { Injectable } from '@angular/core';
    import { AngularFireList, AngularFireDatabase } from '@angular/fire/database';
    import { Item } from '../models/product';

    @Injectable({
      providedIn: 'root'
    })
    export class ProductsService {
      constructor(
        private db: AngularFireDatabase
      ) { }

      create(product) {
        return this.db.list('/products').push(product);
      }
      getAll() {
        return this.db.list('/products').valueChanges();
      }
      get(productId) {
        return this.db.object('/products/' + productId).valueChanges();
      }
    }

3 个答案:

答案 0 :(得分:1)

this.product是在预订中分配的,但是在呈现模板时仍未定义,访问模板中的observables值时应使用异步管道,或将product.title的使用情况与ngIf一起包装产品对象。

答案 1 :(得分:0)

您正在做jQuery("input[type='radio']:checked").each(function(){ let name = jQuery(this).attr("name"); jQuery("#"+name).addClass("solved"); }) 。不确定,但我认为可观察值的第一个值可能不确定。尝试使用take(1),但我也建议您不要使用订阅,而应使用异步管道

答案 2 :(得分:0)

需要采取一些步骤: 1.创建一个接口并声明所有输入参数:product.ts

   export interface Product {
      key?: string;
      title: string;
      price: number;
      etc...
}
  1. 在product.service.ts中:

    getAll(){ 返回this.db.list('/ products /') .snapshotChanges() 。管( map(动作=> actions.map(a =>({键:a.payload.key,...(a.payload.val()as {})})) ) ); }

  2. 在my.ts中,声明d并替换let ID和if(),如下所示:

    id; this.id = this.route.snapshot.paramMap.get('id'); 如果(this.id) this.productService.get(this.id) .subscribe(p => this.product = p);

4。尝试