I'm trying to chain / pipe operations and return an Observable from a Service in angular which uses angular fire.
With promises I have this working
Service
saveDiploma(diploma: { title: any; description: any; picture: any }) {
return new Observable(observer => {
const id = this.db.createId();
this.storage.ref(`diplomas/${id}/original.jpg`)
.putString(diploma.picture, 'data_url')
.then(task => {
task.ref.getDownloadURL()
.then(url => {
const saved = {
title: diploma.title,
description: diploma.description,
url,
createdAt: firebase.firestore.FieldValue.serverTimestamp(),
createdBy: this.auth.auth.currentUser ? this.auth.auth.currentUser.uid : 'anonymous'
};
this.db.doc(`diplomas/${id}`)
.set(saved)
.then(() => {
observer.next(saved);
observer.complete();
})
.catch(e => observer.error(e));
})
.catch(e => observer.error(e));
})
.catch(e => observer.error(e));
});
}
Component
save() {
this.diplomasService.saveDiploma({
title: this.diplomaForm.value.title,
description: this.diplomaForm.value.description,
picture: this.currentImage
}).subscribe(diploma => {
console.log('saved diploma', diploma);
}, e => console.error('error while saving the diploma', e));
}
I'm trying to use Observables in the service instead of Promises and pipe them in order like so
saveDiploma(diploma: { title: any; description: any; picture: any }) {
const id = this.db.createId();
const ref = this.storage.ref(`diplomas/${id}/original.jpg`);
return ref.putString(diploma.picture, 'data_url').snapshotChanges().pipe(
concatMap(task => {
console.log('getDownloadURL');
return from(task.ref.getDownloadURL());
}),
concatMap(url => {
console.log('url', url);
const saved = {
title: diploma.title,
description: diploma.description,
url,
createdAt: firebase.firestore.FieldValue.serverTimestamp(),
createdBy: this.auth.auth.currentUser ? this.auth.auth.currentUser.uid : 'anonymous'
};
return from(this.db.doc(`diplomas/${id}`).set(saved));
})
);
}
but the getDownloadURL method is getting fired before the upload is complete and hence returning an error storage/object-not-found
. I've tried adding a finalize or filter (on task.state == 'success') before the concatMap(getDownloadURL) but I have failed getting it to work.
Does anyone know how to pipe this operations and return an Observable from them?
I'm using Angular 8.1.2, Angular Fire 5.2.1 and rxjs 6.5.1