简体   繁体   English

我想编辑我的产品列表时遇到问题,出现此错误无法读取null的属性“ title”

[英]I have an issue when I want to edit my product list and i am getting this error Cannot read property 'title' of null

I have an issue after my data is stored in db and I want to edit it. 我的数据存储在db中后出现问题,我想对其进行编辑。 It is not showing data and I am getting cannot read property error. 它没有显示数据,我无法读取属性错误。

Html HTML

admin-products.component.html admin-products.component.html

<p>
  <a routerLink="/admin/products/new" class="btn btn-primary">New Products</a>
</p>
<table class="table">
  <thead>
    <tr>
      <th>Title</th>
      <th>Price</th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr *ngFor="let p of products$ | async">
      <td>{{ p.title }}</td>
      <td>{{ p.price }}</td>
      <td><a [routerLink]="['/admin/products/', p.$key]">Edit</a></td>
    </tr>
  </tbody>
</table>

product-form.component.html product-form.component.html

If I check error link in console it is showing an error at all input field. 如果我在控制台中检查错误链接,则所有输入字段均显示错误。 I think mostly error may b here ? 我认为大多数错误可能在这里?

    <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-prepend">
          <span class="input-group-text"> $ </span>
          <input
            #price="ngModel"
            [(ngModel)]="product.price"
            name="price"
            id="price"
            type="number"
            class="form-control"
            required
            [min]="0"
          />
        </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 or higher.</div>
        </div>
      </div>
      <div class="form-group">
        <label for="category">Category</label>
        <select
          #category="ngModel"
          [(ngModel)]="product.category"
          name="category"
          id="category"
          class="form-control"
          required
        >
          <option value=""></option>
          <option *ngFor="let c of categories$ | async" [value]="c.$key">
            {{ 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)]="product.imageUrl"
          name="imageUrl"
          id="imageUrl"
          type="text"
          class="form-control"
          required
          url
        />
        <div
          class="alert alert-danger"
          *ngIf="imageUrl.touched && imageUrl.invalid"
        >
          <div *ngIf="imageUrl.errors.required">Image is required</div>
          <div *ngIf="imageUrl.errors.url">Please enter a vaild 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
        class="card-img-top"
        [src]="product.imageUrl"
        *ngIf="product.imageUrl"
      />
      <div class="card-body">
        <h5 class="card-title">{{ product.title }}</h5>
        <p class="card-text">{{ product.price | currency: 'USD':true }}</p>
      </div>
    </div>
  </div>
</div>

product-form.component.ts 产品表格。组件

    import { Component } from '@angular/core';
import { CategoryService } from 'src/app/category.service';
import { ProductService } from 'src/app/product.service';
import { Router, ActivatedRoute } from '@angular/router';
import 'rxjs/add/operator/take';

@Component({
  selector: 'app-product-form',
  templateUrl: './product-form.component.html',
  styleUrls: ['./product-form.component.css']
})
export class ProductFormComponent {
  categories$;
  product = {};

  constructor(
    private router: Router,
    private route: ActivatedRoute,
    private categoryService: CategoryService,
    private productService: ProductService
  ) {
    this.categories$ = categoryService.getCategories();

    // tslint:disable-next-line:prefer-const
    let id = this.route.snapshot.paramMap.get('id');
    // tslint:disable-next-line:curly
    if (id)
      this.productService.get(id).valueChanges().take(1).subscribe(p => (this.product = p));
  }

  save(product) {
    this.productService.create(product);
    this.router.navigate(['/admin/products']);
  }
}

product-service.ts 产品服务

import { Injectable } from '@angular/core';
import { AngularFireDatabase, AngularFireList } from 'angularfire2/database';
@Injectable()
export class ProductService {
  products$: AngularFireList<any[]>;
  constructor(private db: AngularFireDatabase) {
    this.products$ = this.db.list('/products');
  }
  create(product) {
    return this.products$.push(product);
  }

  getAll() {
    return this.db.list('/products').valueChanges();
  }

  get(productId) {
    return this.db.object('/products/' + productId);
  }
}

I have tried this method by using *ngIf , [ngModel]="product?.title" 我通过使用* ngIf,[ngModel] =“ product?.title”尝试了此方法

<input *ngIf="title">

Have you tried to wrap your form with ng-container ? 您是否尝试过用ng-container包装表格?

product-form.component.ts 产品表格。组件

@Component({
  selector: 'app-product-form',
  templateUrl: './product-form.component.html',
  styleUrls: ['./product-form.component.css']
})
export class ProductFormComponent {
  categories$;
  product = null;

  constructor(
    private router: Router,
    private route: ActivatedRoute,
    private categoryService: CategoryService,
    private productService: ProductService
  ) {
    this.categories$ = categoryService.getCategories();

    // tslint:disable-next-line:prefer-const
    let id = this.route.snapshot.paramMap.get('id');
    // tslint:disable-next-line:curly
    if (id)
      this.productService.get(id).valueChanges().take(1).subscribe(p => (this.product = p));
  }

  save(product) {
    this.productService.create(product);
    this.router.navigate(['/admin/products']);
  }
}

product-form.component.html product-form.component.html

<div class="row">
  <div class="col-md-6">
    <ng-container *ngIf="product">
       <form #f="ngForm" (ngSubmit)="save(f.value)">
       <!-- YOUR CODE -->
       </form>
    </ng-container>
  </div>
</div>

Try this, 尝试这个,

export class ProductFormComponent {
  categories$;
  product = {
               "title": '',
               "price": '', 
               "category": '',
               "imageUrl": '',                
            };



constructor(
        private router: Router,
        private route: ActivatedRoute,
        private categoryService: CategoryService,
        private productService: ProductService
      ) {
        this.categories$ = categoryService.getCategories();

        // tslint:disable-next-line:prefer-const
        let id = this.route.snapshot.paramMap.get('id');
        // tslint:disable-next-line:curly
        if (id)
          this.productService.get(id).valueChanges().take(1).subscribe(p => (this.product = p));
      }

      save(product) {
        this.productService.create(product);
        this.router.navigate(['/admin/products']);
      }
    }

The reason it is failing because 之所以失败,是因为

this.productService.get(id).valueChanges().take(1).subscribe(p => (this.product = p));

the above line will take time to get the response from the firebase, In the meantime, the HTML component will be rendered before that, so it is trying to access product object in the HTML component, since there is no title, price, category, and imageUrl in product object it will cause the error. 上一行需要花费一些时间才能从Firebase获得响应,与此同时,HTML组件将在此之前呈现,因此,由于没有标题,价格,类别,因此它试图访问HTML组件中的产品对象,产品对象中的imageUrl会导致错误。 So assign the empty values, later it is updated once you receive the response 因此,分配空值,稍后在收到响应后将其更新

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么会出现“无法读取null的属性样式”错误? - Why I am getting “cannot read property style of null” error? 使用解析的字符串时,为什么会出现错误“无法读取null的属性&#39;名称&#39;”? - Why am I getting error 'Cannot read property 'name' of null' when using a parsed string? 为什么我收到此错误:“未捕获的TypeError:无法读取未定义的属性'标题'”? - Why am i getting this error: “Uncaught TypeError: Cannot read property 'Title' of undefined”? 无法读取 null 错误的属性“innerHTML”。 我的脚本在正文的末尾,为什么我仍然收到此错误? - Cannot read property 'innerHTML' of null error. My script is at the end of the body, why am I still getting this error? 为什么我无法读取 null javascript 的属性“addEventListener” - why i am getting Cannot read property 'addEventListener' of null javascript 为什么我收到 null 的“无法读取属性”“addEventListener” - Why am i getting 'Cannot read property 'addEventListener' of null 为什么我的脚本中出现“未捕获的TypeError:无法读取null的属性&#39;nodeName&#39;”? - Why am I getting “Uncaught TypeError: Cannot read property 'nodeName' of null” in my script? 获取“无法读取null的属性&#39;innerHTML&#39;”,但我启动了该ID - Getting “Cannot read property 'innerHTML' of null” but I have that id initiated 当我想获取数据时出现此错误:TypeError:无法读取未定义的属性“数据” - When i want to fetch data i have this error : TypeError: Cannot read property 'data' of undefined 为什么我使用Knockout JS获得“无法读取属性'nodeType'的null”错误? - Why am I getting a “Cannot read property 'nodeType' of null” error with Knockout JS?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM