问题描述
我正在尝试进行链/管道操作,并从使用角火的角度服务中返回一个Observable.
I'm trying to chain / pipe operations and return an Observable from a Service in angular which uses angular fire.
凭诺言我有这个工作
服务
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));
});
}
组件
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));
}
我正在尝试在服务中使用Observables而不是Promises,并通过管道像这样
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));
})
);
}
有人知道如何通过管道传递此操作并从中返回一个Observable吗?
Does anyone know how to pipe this operations and return an Observable from them?
我正在使用Angular 8.1.2,Angular Fire 5.2.1和rxjs 6.5.1
I'm using Angular 8.1.2, Angular Fire 5.2.1 and rxjs 6.5.1
推荐答案
根据AngularFire文档 ref.putString(..).snapshotChanges()
According to the AngularFire documentation ref.putString(..).snapshotChanges()
所以您的问题是 .snapshotChanges()
在文件上传完成之前发出了. concatMap
不仅在完成时还会在源中的每次发射中触发.您应该使用 concat
.
saveDiploma(diploma: { title: any; description: any; picture: any }) {
const id = this.db.createId();
const ref = this.storage.ref(`diplomas/${id}/original.jpg`);
return concat(
ref.putString(diploma.picture, 'data_url').snapshotChanges().pipe(ignoreElements()),
defer(() => ref.getDownloadURL().pipe(
switchMap(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 this.db.doc(`diplomas/${id}`).set(saved); // you can return a Promise directly
})
))
);
}
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(
last(),
switchMap(() => ref.getDownloadURL()),
map(url => ({
title: diploma.title,
description: diploma.description,
url,
createdAt: firebase.firestore.FieldValue.serverTimestamp(),
createdBy: this.auth.auth.currentUser ? this.auth.auth.currentUser.uid : 'anonymous'
})),
switchMap(saved => this.db.doc(`diplomas/${id}`).set(saved))
);
}
这篇关于链管操作后如何以角度返回服务中的可观测对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!