Search code examples
javascriptarraysjsonrecursionmootools

mootools javascript return Array.each() with recursion


I have a JSON object and what I'm trying to achieve is, that I can search the object for child_objects by id. I am using an Array.each() and a function with recursion like the following:

1  Template.get_object_attributes_by_id = function(id, template)
2  {
3    var template_obj = JSON.parse(template);
4    console.log(Template.check_for_id_equality(template_obj, id);
5    return Template.check_for_id_equality(template_obj, id);
6  }
7 
8  Template.check_for_id_equality = function(obj, id)
9  {
10   if (obj.attrs.id !== id) {
11     if (obj.children === null || obj.children === undefined) {
12       return;
13     }
14     Array.each(obj.children, function(obj_child) {
15       return Template.check_for_id_equality(obj_child, id);
16     });
17   }
18   else {
19     console.log(obj);
20     return obj;
21   }
22 }

The output of line 19 is the correct object after calling Template.get_object_attributes_by_id(id, template), but the output of line 4 is undefined. It seems that Array.each() "ignores" the return and just keeps going. So now my question is, how to correctly return the object, so that I will get it in the function get_object_attributes_by_id().

Update:

The input (the template) is an JSON object like the following, in which I am searching for the id "placeholder-2" for example. It's just an example, so please do not look for missing brackets or something like this, because the real JSON object that I'm using is clearly valid.

{
  "className":"Stage",
  "attrs":{
    "width":1337,
    "height":4711
  },
  "children":[{
    "className":"Layer",
    "id":"placeholder-layer",
    "attrs":{
      "width":1337,
      "height": 4711
    },
    "children":[{
      "className":"Text",
      "id":"placeholder-1",
      "attrs":{
        "fontsize":42,
        "color":"black",
        ...
      }
    },
    {
      "className":"Text",
      "id":"placeholder-2",
      "attrs":{
        "fontsize":37,
        "color":"red",
        ...
      }
    },
    ...
    ]
  }]
}

And this would the expected output:

{
  "className":"Text",
  "id":"placeholder-2",
  "attrs":{
    "fontsize":37,
    "color":"red",
    ...
  },
}

Solution

  • After a little bit more investigating and trying, my colleague and I solved the problem ourselves, by using a "for"-loop instead of "Array.each()".

    Here's the solution:

    1  Template.get_object_attributes_by_id = function(id, template)
    2  {
    3    var template_obj = JSON.parse(template);
    4    console.log(Template.check_for_id_equality(template_obj, id);
    5    return Template.check_for_id_equality(template_obj, id);
    6  }
    7 
    8  Template.check_for_id_equality = function(obj, id)
    9  {
    10   if (obj.attrs.id === id) {
    11     return obj;
    12   }
    13   if (obj.children === null || obj.children === undefined) {
    14       return false;
    15   }
    16   for (var i = 0; i < obj.children.length; i++) {
    17     var ret_val = Template.check_for_id_equality(obj.children[i], id);
    18     if (ret_val !== false) {
    19       return ret_val;
    20     }
    21   }
    22   return false;
    23 }