-3

I have a JSON field object

{path: 'field', children: []}

that can be nested like this:

$scope.fields = [{path: 'field1', children:
                            [{path: 'field1.one', children: []},
                             {path: 'field1.two', children: []}]},
                        {path: 'field2', children: []}];

I am using the following function to iterate among the nested fields to retrieve the field with a specified path:

var getField = function(thisPath, theseFields) {

        if (arguments.length == 1) {
            theseFields = $scope.fields;
        }
        angular.forEach(theseFields, function(field) {
            if (field.path == thisPath) {
                console.log('returning: '+JSON.stringify(field));
                return field;
            }
            if (field.children != null) {
                return getField(thisPath, field.children);
            }
        });
    };

This call

console.log('field1.one: '+ JSON.stringify(getField('field1.one')));

generates the following logging in the browser console:

returning: {"path":"field1.one","children":[]}
field1.one: undefined

The target field is found but never returned!

I get the same result with or without the return in the method call

return getField(thisPath, field.children)

What am I missing? See working plunkr.

  • Consider which function your `return` statements are returning from (hint: it's not `getField`). This is a case where a good old fashioned `for` loop would be useful. – James Thorpe Mar 21 '18 at 17:02

2 Answers2

-2

In this solution I use an exception when the field is found, and immediately this breaks the loop.

const fields = [
  {
    path: 'field1', 
    children:[ 
      { 
        path: 'field1.one', 
        children: [
          { 
            path: 'field1.one.one', 
            children: [
              { 
                path: 'field1.one.one.one', 
                children: [ ]
              }
            ]
          }
        ]
      },
      {
        path: 'field1.two', 
        children: []
      }
    ]
  },
  {
    path: 'field2', 
    children:[ ]
  }
]

getField = ( fields, fieldToFind ) => {
  
  fields.map( ( field ) => {
      
     if ( field.path === fieldToFind ) {
       
       /**
       * break map 
       * avoid continue loop
       */
       throw { field: field }
       
     } else {
       
       getField( field.children, fieldToFind );
       
     }
    
  } )
  
}

try {
  
  getField( fields, 'field1.one.one.one' );
  
} catch( field ) {
  
  console.log( field );
  
}
-5
    var getField = function(thisPath, theseFields) {
        var result = null;
        if (arguments.length == 1) {
            theseFields = $scope.fields;
        }
        angular.forEach(theseFields, function(field) {
            var test;
            if (field.path == thisPath) {
                console.log('returning: '+JSON.stringify(field));
                result = field;
            }
            if (field.children != null) {
                test = getField(thisPath, field.children);
                if(test!=null)
                  result = test;
            }
        });
        return result;
    }
webnetweaver
  • 192
  • 8