Get possible question answer paths (JavaScript)

Welcome to Programming Tutorial official website. Today - we are going to cover how to solve / find the solution of this error Get possible question answer paths (JavaScript) on this date .

I’m looking to get all the possible question answer paths based on question options, I’ve been racking my brain all day and can’t seem to figure out why my code isn’t working.

Test Code:

const originalQuestions = {
    1: {
        title: "Title",
        firstQuestion: true,
        options: [{
            tooltip: "",
            nextQuestion: 2
        }, {
            tooltip: "",
            nextQuestion: 2
        }, {
            tooltip: "",
            nextQuestion: 10000
        }]
    },
    2: {
        title: "Title",
        options: [{
            tooltip: "",
            nextQuestion: 3
        }, {
            tooltip: "",
            nextQuestion: 3
        }, {
            tooltip: "",
            nextQuestion: 3
        }, {
            tooltip: "",
            nextQuestion: 3
        }]
    },
    3: {
        title: "Title",
        options: [{
            tooltip: "",
            nextQuestion: 4
        }, {
            tooltip: "",
            nextQuestion: 4
        }, {
            tooltip: "",
            nextQuestion: 4
        }]
    },
    4: {
        title: "Title",
        options: [{
            tooltip: "",
            nextQuestion: 13
        }, {
            tooltip: "",
            nextQuestion: 5
        }]
    },
    5: {
        title: "Title",
        options: [{
            tooltip: "",
            nextQuestion: 6
        }, {
            tooltip: "",
            nextQuestion: 6
        }, {
            tooltip: "",
            nextQuestion: 6
        }, {
            tooltip: "",
            nextQuestion: 10000
        }]
    },
    6: {
        title: "Title",
        options: [{
            tooltip: "",
            nextQuestion: 7
        }, {
            tooltip: "",
            nextQuestion: 7
        }, {
            tooltip: "",
            nextQuestion: 7
        }, {
            tooltip: "",
            nextQuestion: 7
        }, {
            tooltip: "",
            nextQuestion: 14
        }]
    },
    7: {
        title: "Title",
        options: [{
            tooltip: "",
            nextQuestion: 17
        }, {
            tooltip: "",
            nextQuestion: 17
        }, {
            tooltip: "",
            nextQuestion: 17
        }, {
            tooltip: "",
            nextQuestion: 17
        }, {
            tooltip: "",
            nextQuestion: 17
        }]
    },
    8: {
        title: "Title",
        options: [{
            tooltip: "",
            nextQuestion: 9
        }, {
            tooltip: "",
            nextQuestion: 9
        }, {
            tooltip: "",
            nextQuestion: 9
        }]
    },
    9: {
        title: "Title",
        options: [{
            tooltip: "",
            nextQuestion: 10
        }, {
            tooltip: "",
            nextQuestion: 10
        }, {
            tooltip: "",
            nextQuestion: 10
        }]
    },
    10: {
        title: "Title",
        options: [{
            tooltip: "",
            nextQuestion: 11
        }, {
            value: "Roof",
            attribute: "Flue Exit",
            tooltip: "",
            nextQuestion: 15
        }]
    },
    11: {
        title: "Title",
        options: [{
            tooltip: "",
            nextQuestion: 12
        }, {
            tooltip: "",
            nextQuestion: 12
        }]
    },
    12: {
        finalQuestion: true,
        input: true,
        placeHolder: 'e.g SWS'
    },
    13: {
        title: "Title",
        options: [{
            tooltip: "",
            nextQuestion: 6
        }, {
            tooltip: "",
            nextQuestion: 6
        }]
    },
    14: {
        title: "Title",
        options: [{
            tooltip: "",
            nextQuestion: 7
        }, {
            tooltip: "",
            nextQuestion: 7
        }, {
            tooltip: "",
            nextQuestion: 10000
        }]
    },
    15: {
        title: "Title",
        options: [{
            tooltip: "",
            nextQuestion: 12
        }, {
            tooltip: "",
            nextQuestion: 12
        }]
    },
    17: {
        title: "Title",
        options: [{
            tooltip: "",
            nextQuestion: 8
        }, {
            tooltip: "",
            nextQuestion: 8
        }, {
            tooltip: "",
            nextQuestion: 8
        }, {
            tooltip: "",
            nextQuestion: 8
        }, {
            tooltip: "",
            nextQuestion: 8
        }]
    },
    // Errors
    10000: {
        isError: true,
        title: "Finally, what is the first part of your postcode?",
        error: "Postcode"
    }
};

function loopPaths(currentArrayPath, questionNum, currentQuestion, paths) {

    if (questionNum > 5) {
   return false;
  }

    if (typeof currentQuestion.finalQuestion != 'undefined') {
    return false;
  } else {
    const question = currentQuestion.options;  
    const validPaths = question.filter((e) => e.nextQuestion !== 10000);   
    const clonedPath = [...paths[currentArrayPath][0]];
            
    for (var i = 0; i < validPaths.length; i++) {
      const e = validPaths[i];
            
      if (typeof paths[currentArrayPath][i] == 'undefined') {
        paths[currentArrayPath][i] = [...clonedPath];
      }
      
      paths[currentArrayPath][i].push(questionNum);
      
      loopPaths(currentArrayPath, e.nextQuestion, originalQuestions[e.nextQuestion], paths);
    }
  }
}

function possiblePaths() {
    const question1 = originalQuestions[1].options;
    const validPaths = question1.filter((e) => e.nextQuestion !== 10000);
  
  let paths = [];
  
  /*validPaths.forEach((e, i) => {
    paths[i] = [[1]];
  });*/
      
  /* 
  for (var i = 0; i < validPaths.length; i++) {
    const e = validPaths[i];
           
    loopPaths(e.nextQuestion, boilerQuestions[e.nextQuestion], paths);
  }   */
  
  // Testing with first question, first option
  paths[0] = [[1]];
  loopPaths(0, 2, originalQuestions[2], paths);
  
  console.log(paths);
}

possiblePaths();

What seems to be happening: (It’s not building the correct paths and not building the different possiblities)

[
  [
    [
      1,
      2,
      3,
      4,
      5,
      4,
      5,
      4,
      5,
      3,
      4,
      5,
      4,
      5,
      4,
      5,
      3,
      4,
      5,
      4,
      5,
      4,
      5,
      3,
      4,
      5,
      4,
      5,
      4,
      5
    ],
    [
      1,
      2,
      3,
      4,
      5,
      3,
      4,
      5,
      4,
      5,
      2,
      4,
      5,
      3,
      4,
      5,
      4,
      5,
      4,
      5,
      3,
      4,
      5,
      4,
      5,
      4,
      5,
      3,
      4,
      5,
      4,
      5
    ]
  ]
]

Example of what it should show: (I’m wondering if there is an easier way to build the different possibilities from 1 -> to the final question which is 12)

[
  [
    [
      1,
      2,
      3,
      4,
      13,
      7,
      17,
      8,
      9,
      10,
      11,
      12
    ],
    [
      1,
      2,
      3,
      4,
      5,
      6,
      7,
      ....
    ]
  ]
]

How it would work:

User hits question 1 -> Presses option 1 -> User hits question 2 -> Presses option 2 -> User hits question 3 -> Presses option 1 -> User hits question 4 -> Presses option 1 -> User hits question 13

Answer

You can use a recursive generator fuction.

const originalQuestions = { 1: { title: "Title", firstQuestion: true, options: [{ tooltip: "", nextQuestion: 2 }, { tooltip: "", nextQuestion: 2 }, { tooltip: "", nextQuestion: 10000 }] }, 2: { title: "Title", options: [{ tooltip: "", nextQuestion: 3 }, { tooltip: "", nextQuestion: 3 }, { tooltip: "", nextQuestion: 3 }, { tooltip: "", nextQuestion: 3 }] }, 3: { title: "Title", options: [{ tooltip: "", nextQuestion: 4 }, { tooltip: "", nextQuestion: 4 }, { tooltip: "", nextQuestion: 4 }] }, 4: { title: "Title", options: [{ tooltip: "", nextQuestion: 13 }, { tooltip: "", nextQuestion: 5 }] }, 5: { title: "Title", options: [{ tooltip: "", nextQuestion: 6 }, { tooltip: "", nextQuestion: 6 }, { tooltip: "", nextQuestion: 6 }, { tooltip: "", nextQuestion: 10000 }] }, 6: { title: "Title", options: [{ tooltip: "", nextQuestion: 7 }, { tooltip: "", nextQuestion: 7 }, { tooltip: "", nextQuestion: 7 }, { tooltip: "", nextQuestion: 7 }, { tooltip: "", nextQuestion: 14 }] }, 7: { title: "Title", options: [{ tooltip: "", nextQuestion: 17 }, { tooltip: "", nextQuestion: 17 }, { tooltip: "", nextQuestion: 17 }, { tooltip: "", nextQuestion: 17 }, { tooltip: "", nextQuestion: 17 }] }, 8: { title: "Title", options: [{ tooltip: "", nextQuestion: 9 }, { tooltip: "", nextQuestion: 9 }, { tooltip: "", nextQuestion: 9 }] }, 9: { title: "Title", options: [{ tooltip: "", nextQuestion: 10 }, { tooltip: "", nextQuestion: 10 }, { tooltip: "", nextQuestion: 10 }] }, 10: { title: "Title", options: [{ tooltip: "", nextQuestion: 11 }, { value: "Roof", attribute: "Flue Exit", tooltip: "", nextQuestion: 15 }] }, 11: { title: "Title", options: [{ tooltip: "", nextQuestion: 12 }, { tooltip: "", nextQuestion: 12 }] }, 12: { finalQuestion: true, input: true, placeHolder: 'e.g SWS' }, 13: { title: "Title", options: [{ tooltip: "", nextQuestion: 6 }, { tooltip: "", nextQuestion: 6 }] }, 14: { title: "Title", options: [{ tooltip: "", nextQuestion: 7 }, { tooltip: "", nextQuestion: 7 }, { tooltip: "", nextQuestion: 10000 }] }, 15: { title: "Title", options: [{ tooltip: "", nextQuestion: 12 }, { tooltip: "", nextQuestion: 12 }] }, 17: { title: "Title", options: [{ tooltip: "", nextQuestion: 8 }, { tooltip: "", nextQuestion: 8 }, { tooltip: "", nextQuestion: 8 }, { tooltip: "", nextQuestion: 8 }, { tooltip: "", nextQuestion: 8 }] }, 10000: { isError: true, title: "Finally, what is the first part of your postcode?", error: "Postcode" } };

function* fnName(key, result = [key]) {
    let options = originalQuestions[key]?.options;
    if (!options) yield result
    else for (const id of new Set(options.map(v => v.nextQuestion)))
        yield* fnName(id, result.concat(id));
}
console.log("Prettify", Array.from(fnName(1), path => path.join(", ")))

I simple pass 1st question id (fnName(1)), in this case its number 1 Because this is the 1st question. (originalQuestions[1].firstQuestion = true)