1

In Firestore, I am trying to update documents in a loop with the batch method.

How come this code works :

var batch = this.afs.firestore.batch();
var eventRef = this.eventCollection.doc(eventkey).ref;
batch.update(eventRef, updateField );
var artistRef = this.memberCollection.doc('7yLf6RgLIIEUkAJ3jbXy').collection('events').doc(eventkey).ref; 
batch.update(artistRef, updateField); 
var artistRef = this.memberCollection.doc('eJtcLZrUZhhObWcmptQs').collection('events').doc(eventkey).ref; 
batch.update(artistRef, updateField); 
batch.commit().then(function() {console.log('success')};

But this one doesn't work :

var batch = this.afs.firestore.batch();
var eventRef = this.eventCollection.doc(eventkey).ref;
batch.update(eventRef, updateField );
if(artists) {
  Object.values(artists).forEach(function(artist) {
    var artistkey = artist.$key;
    var artistRef = this.memberCollection.doc(artistkey).collection('events').doc(eventkey).ref;
    batch.update(artistRef, updateField); 
  });
}
batch.commit().then(function() {console.log('success')};

It tells me "ERROR TypeError: Cannot read property 'memberCollection' of undefined"

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
C. Banzet
  • 409
  • 2
  • 5
  • 19

1 Answers1

3

Since you're inside a callback function, the meaning of this is different from outside of it.

The simplest solution is to assign your memberCollection to a separate variable outside of the callback:

var batch = this.afs.firestore.batch();
var eventRef = this.eventCollection.doc(eventkey).ref;
var memberCollection = this.memberCollection;
batch.update(eventRef, updateField );
if(artists) {
  Object.values(artists).forEach(function(artist) {
    var artistkey = artist.$key;
    var artistRef = memberCollection.doc(artistkey).collection('events').doc(eventkey).ref;
    batch.update(artistRef, updateField); 
  });
}
batch.commit().then(function() {console.log('success')};

But you can also use arrow syntax for functions, which prevents the reassigning of this:

var batch = this.afs.firestore.batch();
var eventRef = this.eventCollection.doc(eventkey).ref;
batch.update(eventRef, updateField );
if(artists) {
  Object.values(artists).forEach((artist) => {
    var artistkey = artist.$key;
    var artistRef = this.memberCollection.doc(artistkey).collection('events').doc(eventkey).ref;
    batch.update(artistRef, updateField); 
  });
}
batch.commit().then(function() {console.log('success')};

This is an extremely common JavaScript question, and applies everywhere you have callbacks (not just with Firestore). I recommend you check out some of the previous questions on this topic:

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807