0

I am trying to create a series of new objects using the values from an existing object to push to my database.

Here is the existing object:

{
  name: 'Pasta',
  method: 'Cook pasta',
  ingredients: [
    { measure: 'tbsp', quantity: '1', ingredient_name: 'lemon' },
    { measure: 'g', quantity: '1', ingredient_name: 'salt' },
    { measure: 'packet', quantity: '1', ingredient_name: 'spaghetti' },
    { measure: 'litre', quantity: '1', ingredient_name: 'water' }
  ]
}

Basically I have a function that inserts and returns the id of the recipe into one table, then inserts and returns/or finds the ids of the relevant ingredients and the final part (with which I am struggling) is to combine the returned recipe_id, ingredient_id and the correct measure and quantity (as written in the object above).

Here is where I have gotten to:

//starting point is here
async function addNewRecipe(newRecipe, db = connection) {
  console.log(newRecipe)
  const recipeDetails = {
    recipe_name: newRecipe.name,
    recipe_method: newRecipe.method,
  }
  const ingredientsArray = newRecipe.ingredients

  const [{ id: recipeId }] = await db('recipes')
    .insert(recipeDetails)
    .returning('id')

  const ingredientsWithIds = await getIngredients(ingredientsArray) //returns an array of ids


  ingredientsWithIds.forEach((ingredientId) => {
    let ingredientRecipeObj = {
      recipe_id: recipeId, //works
      ingredient_id: ingredientId, //works
      measure: newRecipe.ingredients.measure, //not working - not sure how to match it with the relevant property in the newRecipe object above.
      quantity: newRecipe.ingredients.quantity,//not working - not sure how to match it with the relevant property in the newRecipe object above.
    }
    //this is where the db insertion will occur
  })
}

The desired output would be:

ingredientRecipeObj = {
      recipe_id: 1
      ingredient_id: 1
      measure: tbsp
      quantity: 1
} then insert this into db

followed by:
ingredientRecipeObj = {
     recipe_id: 1
     ingredient_id: 2
     measure: g
     quantity: 1
} then insert into db

etc. etc.
8
  • 1
    What's your expected/desired output? Commented Jun 11, 2022 at 8:23
  • What exactly do you want to achieve ? Commented Jun 11, 2022 at 8:25
  • 1
    The problem seems to be that the function "getIngredients" returns only the IDs. Once you have fetched them, you have no way of knowing which ID is for which ingredient. You would have to change that method to make it return an array of both the ID and the ingredient name. Then you could find the ingredient in the ingredient array. Commented Jun 11, 2022 at 8:27
  • thanks for the clarifying questions - I have added desired output to OP. Essentially the forEach would create an object with the recipe's id, and then each ingredient's id from the ingredientIds array and then the relevant measure and quantity from the newRecipe object (which is exampled in OP). Each ingredientObj would then be inserted into db. Commented Jun 11, 2022 at 8:27
  • @FredrikWallén seems accurate, just not sure how best to join them up? Commented Jun 11, 2022 at 8:30

1 Answer 1

1

The problem seems to be that the function "getIngredients" returns only the IDs. Once you have fetched them, you have no way of knowing which ID is for which ingredient. One way to change that is to make the method return an array of both the ID and the ingredient name. Then you could match them like this:

const ingredientsWithIds = await getIngredients(ingredientsArray) //now an array of objects with ingredient_name and id

ingredientsWithIds.forEach((ingredient) => {
    const recipeIngredient = ingredientsArray.find(ri => ri.ingredient_name === ingredient.ingredient_name)
    const ingredientRecipeObj = {
      recipe_id: recipeId,
      ingredient_id: ingredient.id, 
      measure: recipeIngredient.measure, 
      quantity: recipeIngredient.quantity,
    }
    //this is where the db insertion will occur
  })

Since you haven't posted the "getIngredients" function it is hard to say exactly how to adapt it to return the name as well.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.