switchMap函数不执行里面的代码
switchMap function does not execute the code inside it
我正在尝试将带有图片的项目添加到我的 firestore 中,因为 base64 图片大于 2Mb,我正在使用 firestore 存储图像并获取 url 来设置相应的场.
为此,我将我的项目发送到 firebase,图片的字段为空,然后,我将图片发送到 firebase 存储。直到这里一切正常,但是当我尝试下载 url 并将其设置为我的项目时,它不起作用。
这是我的代码:
这是我的页面,我要在其中向 firestore 添加新项目。
export class AddFoodPage implements OnInit {
...
addFood() {
this.setFood();
this.foodService.addFood(this.food, this.foodPicture.base64).then(() => {
this.presentAlert();
this.tagList = [];
this.ingredientList = [];
this.addFoodForm.reset();
});
}
...
private setFood() {
this.food = this.addFoodForm.value;
this.food.ingredientList = this.ingredientList;
this.food.specials = this.tagList;
this.foodPicture = this.imgService.getPicture();
this.food.photoUrl = '';
}
这里是我的项目服务:
export class FoodService {
private foodCollection: AngularFirestoreCollection<FoodView>;
constructor(
private afs: AngularFirestore,
private authService: AuthService,
private storage: AngularFireStorage
) {
this.foodCollection = this.afs.collection('food');
}
async addFood(food: FoodView, base64String: string) {
this.authService.getUserData().subscribe((_user) => {
food.cookerName = _user.displayName;
food.cookerId = _user.uid;
from(this.foodCollection.add(food)).subscribe((addedFood) =>
this.uploadFoodImage(base64String, addedFood.id, food.cookerId)
);
});
}
private uploadFoodImage(
base64String: string,
foodId: string,
userId: string
) {
const filePath = `foods/${userId}/${foodId}`;
const fileRef = this.storage.ref(filePath);
const task: AngularFireUploadTask = fileRef.putString(
base64String,
'base64',
{ contentType: 'image/png' }
);
return from(task).pipe(
switchMap(
(result) => {
return fileRef.getDownloadURL();
}
// Upload Task finished, get URL to the image
),
switchMap((photoUrl) => {
// Set the URL to the food document
const uploadPromise = this.afs
.doc(`food/${foodId}`)
.set(photoUrl, { merge: true });
console.log(photoUrl);
return from(uploadPromise);
})
);
}
上面的代码中,switchMap函数中的代码没有执行,不明白为什么,是不是漏掉了什么?图片已保存到 firebase 存储中,但文档不会在 firestore 中更新。
这是我的食物模型:
export class FoodView {
fid: string;
cookerId: string;
cookerName: string;
title: string;
photoUrl: string;
ingredientList: string[] = [];
type: string;
hasAllergen: boolean;
specials: string[];
origin: string;
price: number;
quantity: number;
}
您可以将 Observable 分为两种不同的类型:“热”和“冷”Observable。使用热可观察对象,您可以在可观察对象表示的函数之外获得发射值的来源。
另一方面,冷可观察对象在其自身的函数中创建源。因此,要使冷可观察对象发出任何值,body 必须至少 运行 一次。
在您的示例中,form(task)
似乎创建了一个冷可观察对象。所以首先要创建数据源,需要通过订阅来调用函数
要缩短它:只需在管道后添加一个 .subscribe()
。
return from(task).pipe(
switchMap(
(result) => {
return fileRef.getDownloadURL();
}
// Upload Task finished, get URL to the image
),
switchMap((photoUrl) => {
// Set the URL to the food document
const uploadPromise = this.afs
.doc(`food/${foodId}`)
.set(photoUrl, { merge: true });
console.log(photoUrl);
return from(uploadPromise);
})
).subscribe();
我正在尝试将带有图片的项目添加到我的 firestore 中,因为 base64 图片大于 2Mb,我正在使用 firestore 存储图像并获取 url 来设置相应的场.
为此,我将我的项目发送到 firebase,图片的字段为空,然后,我将图片发送到 firebase 存储。直到这里一切正常,但是当我尝试下载 url 并将其设置为我的项目时,它不起作用。
这是我的代码:
这是我的页面,我要在其中向 firestore 添加新项目。
export class AddFoodPage implements OnInit {
...
addFood() {
this.setFood();
this.foodService.addFood(this.food, this.foodPicture.base64).then(() => {
this.presentAlert();
this.tagList = [];
this.ingredientList = [];
this.addFoodForm.reset();
});
}
...
private setFood() {
this.food = this.addFoodForm.value;
this.food.ingredientList = this.ingredientList;
this.food.specials = this.tagList;
this.foodPicture = this.imgService.getPicture();
this.food.photoUrl = '';
}
这里是我的项目服务:
export class FoodService {
private foodCollection: AngularFirestoreCollection<FoodView>;
constructor(
private afs: AngularFirestore,
private authService: AuthService,
private storage: AngularFireStorage
) {
this.foodCollection = this.afs.collection('food');
}
async addFood(food: FoodView, base64String: string) {
this.authService.getUserData().subscribe((_user) => {
food.cookerName = _user.displayName;
food.cookerId = _user.uid;
from(this.foodCollection.add(food)).subscribe((addedFood) =>
this.uploadFoodImage(base64String, addedFood.id, food.cookerId)
);
});
}
private uploadFoodImage(
base64String: string,
foodId: string,
userId: string
) {
const filePath = `foods/${userId}/${foodId}`;
const fileRef = this.storage.ref(filePath);
const task: AngularFireUploadTask = fileRef.putString(
base64String,
'base64',
{ contentType: 'image/png' }
);
return from(task).pipe(
switchMap(
(result) => {
return fileRef.getDownloadURL();
}
// Upload Task finished, get URL to the image
),
switchMap((photoUrl) => {
// Set the URL to the food document
const uploadPromise = this.afs
.doc(`food/${foodId}`)
.set(photoUrl, { merge: true });
console.log(photoUrl);
return from(uploadPromise);
})
);
}
上面的代码中,switchMap函数中的代码没有执行,不明白为什么,是不是漏掉了什么?图片已保存到 firebase 存储中,但文档不会在 firestore 中更新。
这是我的食物模型:
export class FoodView {
fid: string;
cookerId: string;
cookerName: string;
title: string;
photoUrl: string;
ingredientList: string[] = [];
type: string;
hasAllergen: boolean;
specials: string[];
origin: string;
price: number;
quantity: number;
}
您可以将 Observable 分为两种不同的类型:“热”和“冷”Observable。使用热可观察对象,您可以在可观察对象表示的函数之外获得发射值的来源。 另一方面,冷可观察对象在其自身的函数中创建源。因此,要使冷可观察对象发出任何值,body 必须至少 运行 一次。
在您的示例中,form(task)
似乎创建了一个冷可观察对象。所以首先要创建数据源,需要通过订阅来调用函数
要缩短它:只需在管道后添加一个 .subscribe()
。
return from(task).pipe(
switchMap(
(result) => {
return fileRef.getDownloadURL();
}
// Upload Task finished, get URL to the image
),
switchMap((photoUrl) => {
// Set the URL to the food document
const uploadPromise = this.afs
.doc(`food/${foodId}`)
.set(photoUrl, { merge: true });
console.log(photoUrl);
return from(uploadPromise);
})
).subscribe();