NestJS读取嵌套JSON遇map未定义错误,求修正及forEach替代方案
嵌套JSON请求体处理问题:修复"map undefined"错误及forEach替代方案
问题概述
作为TypeScript和NestJS新手,在处理嵌套JSON请求体时遇到问题:请求体包含recipes数组,每个recipe下有ingredients数组,每个ingredient下有nutrients数组。现有代码中ingredientData能正常输出,但获取nutrientData时出现"map undefined"错误,需要修正代码,同时想了解是否能用forEach替代map遍历。
请求JSON示例
{ "recipes": [ { "recipe_id": 1, "ingredients": [ { "ingredient_id": 2, "quantity": 4, "unit": "g", "nutrients": [ { "nutrient_id": 1, "quantity": 2, "unit": "g" } ] }, { "ingredient_id": 3, "quantity": 4, "unit": "g", "nutrients": [ { "nutrient_id": 2, "quantity": 2, "unit": "g" } ] } ] }, { "recipe_id": 2, "ingredients": [ { "ingredient_id": 4, "quantity": 4, "unit": "g", "nutrients": [ { "nutrient_id": 4, "quantity": 2, "unit": "g" } ] }, { "ingredient_id": 5, "quantity": 4, "unit": "g", "nutrients": [ { "nutrient_id": 5, "quantity": 2, "unit": "g" } ] } ] } ] }
现有错误代码
public async createMealRecipe(request) { try{ const ingredientData = request.recipes.flatMap(item => { return item.ingredients.map(({ingredient_id, quantity, unit}) =>{ return { recipe_id: item.recipe_id, ingredient_id, quantity, unit } }) }); const nutrientData = request.recipes.flatMap(item1 => { return item1.nutrients.map(({nutrient_id, quantity, unit}) =>{ return { recipe_id: item1.recipe_id, nutrient_id, quantity, unit } }) }); console.log(ingredientData); console.log(nutrientData); }catch(e) { console.log('e', e); throw e; } }
错误原因
报错核心是:nutrients数组不属于recipe对象(代码里的item1),而是属于每个recipe下的ingredients数组中的单个ingredient对象。直接访问item1.nutrients会得到undefined,对undefined调用map方法自然会抛出错误。
修正后的代码
需要嵌套两层flatMap:先遍历recipes,再遍历每个recipe的ingredients,最后遍历每个ingredient的nutrients,同时保留对应的recipe_id:
public async createMealRecipe(request) { try{ const ingredientData = request.recipes.flatMap(item => { return item.ingredients.map(({ingredient_id, quantity, unit}) =>{ return { recipe_id: item.recipe_id, ingredient_id, quantity, unit } }) }); // 修正后的nutrientData获取逻辑 const nutrientData = request.recipes.flatMap(recipe => { // 先遍历当前recipe的ingredients return recipe.ingredients.flatMap(ingredient => { // 再遍历当前ingredient的nutrients return ingredient.nutrients.map(({nutrient_id, quantity, unit}) =>{ return { recipe_id: recipe.recipe_id, nutrient_id, quantity, unit } }) }) }); console.log(ingredientData); console.log(nutrientData); }catch(e) { console.log('e', e); throw e; } }
用forEach替代map遍历的方案
可以用forEach替代,但forEach本身没有返回值,需要手动声明数组并填充元素:
public async createMealRecipe(request) { try{ // 用forEach替代map获取ingredientData const ingredientData: any[] = []; request.recipes.forEach(recipe => { recipe.ingredients.forEach(({ingredient_id, quantity, unit}) => { ingredientData.push({ recipe_id: recipe.recipe_id, ingredient_id, quantity, unit }) }) }); // 用forEach替代map获取nutrientData const nutrientData: any[] = []; request.recipes.forEach(recipe => { recipe.ingredients.forEach(ingredient => { ingredient.nutrients.forEach(({nutrient_id, quantity, unit}) => { nutrientData.push({ recipe_id: recipe.recipe_id, nutrient_id, quantity, unit }) }) }) }); console.log(ingredientData); console.log(nutrientData); }catch(e) { console.log('e', e); throw e; } }
注意:如果是在TypeScript中,建议给返回的数组元素定义具体的接口类型,代替
any,提升类型安全性。
内容的提问来源于stack exchange,提问作者user3408779
相关产品推荐
相关产品推荐

