1

I would like to get back the result as a return value from the recursion, but I get 'undefined'. I read through all the related solutions (see ***) here, but somehow my example doesn't work. If I'm using a global variable then I can get the result otherwise the return values is 'undefined'.

https://stackblitz.com/edit/typescript-1b2ktw

export interface Needle {
  needles: Needle[];
  text: string;
}

export const Needles: Needle[] = [
  {
    text: 'root',
    needles: [
      {
        text: 'a',
        needles: [
          { text: 'a1', needles: null },
          { text: 'a2', needles: null },
        ],
      },
      { text: 'b', needles: null },
    ],
  },
];

let result;

function findNeedle(needles: Needle[], key: string, value: string): any {
  needles.forEach((x) => {
    if (x[key] === value) {
      // return x as Needle; // doesnt work
      result = x; // works just ugly
    }
    if (x.needles) {
      needles = x.needles;
      // return findNeedle(needles, key, value); solution *** like this doesnt work also
      findNeedle(needles, key, value);
    }
  });
}

console.clear();
let x = findNeedle(Needles, 'text', 'a1');
console.log('x:', x, 'result', result);
--- CONSOLE
Console was cleared
x:undefined, result {text: "a1", needles: null}

How can I fix this to get back the result in return value ?

Thanks in advance.

Csaba

user647314
  • 323
  • 1
  • 4
  • 13
  • 2
    `findNeedle` doesn’t return anything, so why would you expect `return findNeedle(`…`);` or `let x = findNeedle(`…`);` to do anything useful? Also, please see [What does `return` keyword mean inside `forEach` function?](/q/34653612/4642212). – Sebastian Simon Jan 09 '22 at 21:41
  • you are right, when I checked the related question here, many guy mentioned : write return before the recursion. It was just a attempt, just a try. – user647314 Jan 09 '22 at 22:03

2 Answers2

1

Don't use forEach, but a for..of loop. That way you can return something without being trapped within a callback function.

function findNeedle(needles: Needle[], key: string, value: string): any {
  for (let x of needles) {
    if (x[key] === value) return x;
    if (x.needles) {
      result = findNeedle(x.needles, key, value);
      if (result) return result;
    }
  }
}
trincot
  • 317,000
  • 35
  • 244
  • 286
  • Thank you, it works, can you tell me why the first return (if (x[key] === value) return x;) is not enough ? – user647314 Jan 09 '22 at 22:10
  • The first return will only have checked the current object, but nested objects need to be checked also, and that is why `findNeedle` needs to be called recursively on the nested object. – trincot Jan 09 '22 at 22:11
  • 1
    Oh, I got it, since I can get the result from nested calls thats why not enough the first if. Thank you. – user647314 Jan 09 '22 at 22:14
0

x is undefined because findNeedle() doesn't return a result, it assigns one instead to the result variable.

Nathan Wiles
  • 841
  • 10
  • 30
  • yes, but there is a commented line : // return x as Needle; // doesnt work. I just want to prove it works but ugly – user647314 Jan 09 '22 at 22:01