问题描述
我有三个返回观测值的服务。第一个返回配方列表,第二个返回给定配方的所有配料,最后一个返回给定配料类型的数量。我想调用所有三个连续传递先前信息到下一个调用的方法,以便将返回的响应映射到相同的配方初始列表。本质上,每个连续的调用都会添加到先前返回的信息中,并且每个连续的调用都会增加对象列表的复杂性。我还需要对每个返回值应用自定义映射。我还需要他们同时解决问题,因此我可以简单地订阅最终结果。我知道我可能需要使用switchMap或concatMap,但是我不确定如何构造它。
任何帮助将不胜感激
我的服务呼叫及其映射示例
获取食谱
let allRecipes: Observable<RecipeModel[]> = this.recipeListService.GetRecipesFromAirtable(
allTypes,allOccassions,allPrepStyles,allFamilies,muddlingReq,allPrimaryComponents,allSecondaryComponents,recipeName
).pipe(map(response => {
let allRecipes: RecipeModel[] = response.records.map(
recipeObj => {
//console.log(recipeObj.fields);
let model: RecipeModel = {
id: recipeObj.fields["Recipe ID"],name: recipeObj.fields["Name"],variant: '',version: 0,type: recipeObj.fields["Type"]
}
let variant: string = recipeObj.fields["Variant"];
if(variant !== null && variant !== undefined) {
model.variant = variant;
}
let version: number = recipeObj.fields["Version"];
if(version !== null && version !== undefined && isNaN(version) !== true) {
model.version = version;
}
return model;
}
)
return allRecipes;
}));
获取成分
let allIngredients: Observable<IngredientModel[]> = this.ingredientService.GetIngredientsFromAirtable(recipe.id)
.pipe(
map(response => {
let allIngredientObjs: IngredientModel[] = response.records.map(
ingredientObj => {
let model: IngredientModel = {
order: ingredientObj.fields["Order"],name: ingredientObj.fields["Ingredient Name"][0],qualifier: ingredientObj.fields["Qualifier"],optional: ingredientObj.fields["Optional"] ? ingredientObj.fields["Optional"] : false,amountReq: { },notes: ingredientObj.fields["Notes"]
}
let allFields: [string,string][] = [["Cups","cup"],["Ounces","oz"],["Millilitres","mL"],["Quantity",""],["Grams","g"],["Dashes",["Barspoons","barspoons"],["Teaspoons","tsp"],["Misc",""]];
for(let i = 0; i < allFields.length; i++) {
let fieldName: string = allFields[i][0];
let value: string = ingredientObj.fields[fieldName];
if(value === null || value === undefined || value.length == 0) {
continue;
}
model.amountReq[fieldName.toLowerCase()] = {units: allFields[i][1],amount: value};
}
// Add type info
model.type = {
superType: ingredientObj.fields["Ingredient Supertype"],type: ingredientObj.fields["Ingredient Type"],subType: ingredientObj.fields["Ingredient Subtype"]
}
return model;
}
)
return allIngredientObjs;
}));
let ingredientQuantity: Observable<number> = this.inventoryService.GetIngredientQuantitiesFromAirtable(
inventoryName,ingredientName)
.pipe(
map(response => {
let quantity = 0;
let allLiquorObjs = response.records.map(
liquorObj => {
let model = {
brand: liquorObj.fields["Brand"][0],desc: liquorObj.fields["Description"][0],volume: liquorObj.fields["Current Volume (mL)"]
}
if("specialValue" in model.volume) {
model.volume = -1;
}
if(model.volume > 0) {
quantity += model.volume;
}
// return model;
}
)
return quantity;
}));
到目前为止,在Elias Dal Ben的帮助下,我已经完成了以下工作
let allRecipes: Observable<RecipeModel[]> = this.getAllRecipesObservable(this.allDrinkTypes,this.allDrinkOccassions,this.allPreparationStyles,this.allFamilies,this.muddlingrequired,this.allPrimaryComponents,this.allSecondaryComponents,this.recipeNametoFind)
.pipe(
tap(allRecipes => {
console.debug('Recipes(' + allRecipes + ')');
}),concatMap(data => {
let allRecipes = data;
allRecipes.map(
recipe => {
let allIngredients: Observable<IngredientModel[]> = this.getAllIngredientsObservable(recipe);
allIngredients.pipe(
tap(allIngredients => {
console.debug('Ingredients(' + allIngredients + ')');
}),concatMap(data => {
let allIngredients = data;
allIngredients.map(
ingredient => {
let quantity: Observable<number> =
this.getIngredientQuantityObservable(this.inventoryAddr,ingredient.type.name);
quantity.pipe(
tap(quantity => {
console.debug('Quantity(' + quantity + ')');
})
)
return quantity;
}
)
})
)
return allIngredients;
}
)
return allRecipes;
})
)
“类型'Observable'不能分配给类型'Observable
'”
“类型'(data:IngredientModel [])=> void'的参数不能分配给类型'('value:IngredientModel [],index:number)=> ObservableInput'的参数。 类型'void'不能分配给类型'ObservableInput'。”
有人知道我想念什么吗?
解决方法
它非常冗长,但是您可以使用rx/operators
concatMap函数
let result = allRecipes.pipe(
concatMap(recipes => allIngredients.pipe(
concatMap(ingredients => ingredientQuantity.pipe(
map(quantity => [ ...ingredients,...recipes,quantity ])
))
))
)
然后,您只需订阅此结果即可使用[ ...ingredients,quantity ]
结构或任何结构