Получение данных из AngularFirestore из HTML в TypeScript - PullRequest
0 голосов
/ 04 ноября 2018

Это мой первый проект Angular-Firestore. Я хочу получить данные со страницы HTML, которую я вставляю в список данных, используя * ngFor. Когда я нажимаю кнопку отправки на форме. Некоторые данные должны быть введены пользователем, а некоторые поступают из этого цикла * ngFor. Проблема в том, что он выдает следующую ошибку: SellinglistComponent.html: 53 Ошибка: Ошибка вызова функции DocumentReference.set () с недопустимыми данными. Неподдерживаемое значение поля: не определено (найдено в поле ownerID)

Но когда я снова нажимаю кнопку отправки (нажата дважды), она работает без проблем, и я вижу, что данные отправляются в базу данных. Что было бы для этого? Пожалуйста, помогите мне решить это. Спасибо.

Файл TypeScript выглядит следующим образом

import { Component, OnInit, Input } from '@angular/core';
import { PaginationService } from '../pagination.service';
import { AngularFirestore, AngularFirestoreDocument } from 'angularfire2/firestore';
import * as firebase from 'firebase/app';

@Component({
  selector: 'app-sellinglist',
  templateUrl: './sellinglist.component.html',
  styleUrls: ['./sellinglist.component.scss']
})

export class SellinglistComponent implements OnInit 
{
  bidObjectId : string;
  panelOpenState = false;
  public show: boolean;
  public bidName : any;
  bidPrice : number;
  bidAmount : number;
  userRef: AngularFirestoreDocument<{}>;
  ownerID : any;

  constructor(public page1: PaginationService, private db: AngularFirestore) {}

  public openDialog(): void 
  {
    this.show = !this.show;
  }

  ngOnInit() 
  { 
    //iterate through all the saleCrop object using pagination service for more info, refer pagination service component
    this.show = false;
    this.page1.init('saleCrops','postDate', { reverse: true, prepend: false});
    var user = firebase.auth().currentUser;
    var userID = user.uid;
    this.userRef = this.db.doc('users/'+userID);
    this.userRef.ref.get()
    .then((doc) => {
      //checks if the user is logged in and copies their first and last names to the a varible to be used later in the DB
      if(doc.exists) {
        console.log("hello")
        this.bidName = doc.data().fname+" "+doc.data().lname;
      }
      else{
        console.error("No user logged in!");
      }
    })
    console.log(this.bidName)
    
  }

  //Handling the infinite scroll in the marketplace 
  scrollHandler(e) 
  {
    if (e === 'bottom') {
      this.page1.paginate('backward');
    }
  }

  addBid(bidObj)
  {  
    this.bidObjectId = bidObj;
    console.log(bidObj)
    this.db.collection('saleCrops').doc(this.bidObjectId).ref.get()
    .then((doc) => {
      if (doc.exists) {
        console.log(doc.data())
        this.ownerID = doc.data().posterID;
        console.log(1)
        console.log(this.ownerID)
        console.log(2)
      }
      else{
        console.log("error");
      }
    });
    this.db.collection("bids").add({
      bidderName : this.bidName,
      accepted : false,
      bidPrice : this.bidPrice,
      bidAmount : this.bidAmount,
      bidDate : new Date(),
      bidderID : this.userRef.ref,
      objectID : this.bidObjectId,
      ownerID : this.ownerID,
    })
    .then(function() {
      console.log("Bid added Successfully");
    })
    .catch(function(error) {
      console.error("Error Doc: ", error);
    });
  }
}

HTML-файл выглядит следующим образом

<mat-card *ngFor="let saleCrops of page1.data | async">
  <div class="row">
    <div class="example-small-box">
        <img src="{{ saleCrops.photoURL }}" style="object-fit: cover; height: 150px; width: 150px; border-radius: 50%">
    </div>
    <div class="example-small-box">
        <h2 class="">
          <br>
          {{ saleCrops.itemName }}<br/><font size="5">{{ saleCrops.itemAmount }}kg</font><br/><small>Rs. {{ saleCrops.unitPrice }} per 1kg</small>
        </h2>
    </div>
  </div>
    <mat-accordion>
      <mat-expansion-panel (opened)="panelOpenState = true"
      (closed)="panelOpenState = false">
        <mat-expansion-panel-header>
          <mat-panel-title></mat-panel-title>
          <mat-panel-description>
            Click For More Details
          </mat-panel-description>
        </mat-expansion-panel-header>
        <div class="row">
          <div class="example-very-small-box">
            <strong style="font-size: medium">Poster Details</strong> 
            <br><strong>Name</strong> : {{ saleCrops.posterName }}
            <br><strong>Region</strong> : {{ saleCrops.posterRegion }}
            <br>Member Since {{ saleCrops.posterJoinDate.toDate() | date: 'yyyy' }}
          </div>
          <div class="divider"></div>
          <div class="example-long-small-box">
            <div class="description-box"><strong style="font-size: medium">Description</strong> 
              <br><p>
                {{ saleCrops.itemDescription }}
              </p>
            </div>
            <div class="desc-space-box"></div>
          </div>
          <div class="example-very-small-box">
            <strong style="font-size: medium">Current Bid</strong>
            <br><p>Bid Amount : 
            <br>Bidding Price :</p>
            
          </div>
        </div>
        <div class="flex-md-row">
          <button style="width: 120px;" class="btn btn-primary">Contact Seller</button>
          <div class="divider"></div>
          <button style="width: 120px;" class="btn btn-outline-primary" (click)="openDialog()">Place Bid</button>
          <div class="divider"></div>
          <button style="width: 120px;" class="btn btn-danger">Report Seller</button>
        </div>
        <div class="bid-box" *ngIf="show">
          <form (ngSubmit)="addBid(bidObj.value)">
            <input type="text" #bidObj name="bidObjID" [(ngModel)]="saleCrops.doc.id" class="form-control" value="saleCrops.doc.id"  disabled>
            <h6>Bidding Price (in Rupees per kg)</h6>
            <input type="number" name="bidPrice" [(ngModel)]="bidPrice" class="form-control" style="width: 200px">
            <h6>Bidding Amount (in kg)</h6>
            <input type="number" name="bidAmount" [(ngModel)]="bidAmount" class="form-control" style="width: 200px">
            <button class="submit" style="width: 120px;" class="btn btn-primary">Add Bid</button>
          </form>
        </div>
      </mat-expansion-panel>
    </mat-accordion>
</mat-card>
<p *ngIf="page1.done | async">I ran out of stuff to show!</p>
<app-loading-spinner *ngIf="page1.loading"></app-loading-spinner>

1 Ответ

0 голосов
/ 04 ноября 2018

Причина, по которой вы получаете SellinglistComponent.html:53 ERROR Error: Function DocumentReference.set() called with invalid data. Unsupported field value: undefined (found in field ownerID), заключается в том, что вызываемая вами функция асинхронна.

К тому времени, как вы позвоните this.db.collection("bids").add({}), this.db.collection('saleCrops').doc(this.bidObjectId).ref.get() все еще не вернет ответ. Вот почему во второй раз, когда вы звоните, устанавливается this.ownerId.

Вы можете проверить это, позвонив console.log(this.ownerId) непосредственно перед this.db.collection("bids").add({})

Чтобы обеспечить решение, Вы должны сделать функцию асинхронной.

async addBid(bidObj)

Затем вы можете вызвать следующее с ожиданием.

await this.db.collection('saleCrops').doc(this.bidObjectId).ref.get()

Поскольку два блока кодов выглядят зависимыми друг от друга. Вы можете сделать следующее.

Вместо настройки this.ownerID = doc.data().posterID;

Вы можете вернуть это значение следующим образом.

    await this.db.collection('saleCrops').doc(this.bidObjectId).ref.get()
        .then((doc) => {
            if (doc.exists) {
                return doc.data().posterID;
            }
        }).then(id => {
            this.db.collection("bids").add({})
        }).catch(error => console.error(error));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...