Search code examples
angularfirebasegoogle-cloud-firestoreangularfire2ngonchanges

Angularfire2, Firestore Document Retrieval Issue (using .get, possibly related to ngOnChanges)


My application structure has 1 service and 2 components:

Service: Holds all of the firestore connections ViewComponent: Gets a list from the service and displays it ItemManagementComponent: Displays a form and allows the user to add a new entry.

The Issue I have a button in the ViewComponent that (in theory), sends a documentID to the ManagementComponent which then displays that document data in the form, allowing for a user update. Right now, when I click the button I can track the doumentID, and the service return all the way through my application, but I'm not actually getting a document returned. I can run the exact same code with a hardwired documentID, and it works great, so obviously I'm missing something.

Service

  getUpdateInventoryItem(updateId: string) {
    console.log('service', updateId)
    this.updateId = updateId
    console.log('service2', this.inventoryCollectionRef.doc(updateId).ref.get())
    return this.inventoryCollectionRef.doc(updateId).ref.get()
  }

View HTML

<td><button type="button" class="btn btn-default" (click)="updateInventory(item.id)">Upd</button></td>
<app-item-management [updateID]="ChildUpdateId"></app-item-management>

View Component

@Output() inventoryUpdate = new EventEmitter();
public ChildUpdateId: string;

updateInventory(updateId: string) {
this.ChildUpdateId = updateId;
}

ItemManagement Component

@Input() updateID;

  ngOnChanges(incomingID: SimpleChanges) {
    if (!incomingID['updateID'].isFirstChange()) {
      for (let ID in incomingID) {
        let chng = incomingID[ID];
        let cur = JSON.stringify(chng.currentValue);
        console.log('current', cur)
        this.updateInventory(cur)
      }
    }
  }

updateInventory(incomingID) {
    console.log('updateFunction',incomingID)
    this.inventoryService.getUpdateInventoryItem(incomingID)
      .then((doc) => {
        if (doc.exists) {
          this.editItem = doc.data();
          this.inventoryForm.patchValue(this.editItem);
          this.update = true;
        } else {
          console.log("No such document!");
        }
      }).catch(function (error) {
        console.log("Error getting document:", error);
      });
  };

So, if I click on the update button on the view HTML, this is what my console shows me: console log screenshot From my perspective, I'm seeing the ID passed to the service, and the service has a properly formatted document response to return.

If I copy a document ID directly from my console log and hardwire it to the updateInventory function on the ItemManagementComponent, and call the hardwired function from the NgOnChanges it works. It's just that somehow when I'm passing in this ID as a variable it's short circuiting.

I had this same updateInventory function working with a slightly different implementation that took a variable, so I'm really stumped. Any help is greatly appreciated!


Solution

  • The Problem As a total novice, I use a lot of code examples to get things to work, and then try to figure out WHY it worked etc. In this instance, the code snippet I found was using JSON.stringify to set the documentID value. Without realizing the consequences, I left it in.

    let cur = JSON.stringify(chng.currentValue);
    

    What I was missing was a very subtle (to me) clue in the console.

    **Console Return** service "X7hFhwDLzFIicl5uUCEX"
    

    I thought that quotation marks were just a standard notation in the console. Until on a whim I added a console.log on the original button on the view component, and noticed that my return from there didn't have quotation marks:

    service X7hFhwDLzFIicl5uUCEX
    

    All it took to fix this was to change the above stringify line to this:

    let cur: string = chng.currentValue;
    

    Otherwise the rest of the code seems to be doing what I want. Thanks for anyone who took a look!