1

I'm trying to create a menu in AngularJS using template and functional recursion. Unfortunately the code is using a lot of recursion so please lend some help.

Here is the menu data (in JSON):

var menu = {
            'users': {title: 'Users', href: '/admin/users', icon: 'fa-user', 'priority': '2'},
            'dashboard': {title: 'Dashboard', href: '/admin', icon: 'fa-home', badge: null, 'priority': '1'},
            'expert': {title: 'Expert users', href: '', icon: 'fa-cog', 'priority': '3'},
            'logins': {title: 'Social logins', href: '/admin/social-logins', icon: 'fa-lock', 'priority': '2', parent: 'expert'},
            'config': {title: 'Site config', href: '/admin/config', icon: 'fa-cog', 'priority': '1', parent: 'expert'},
            'security': {title: 'Site config', href: '/admin/config', icon: 'fa-key', 'priority': '1', parent: 'config'},
            'deploy': {title: 'Deploy', href: '/admin/deploy', icon: 'fa-upload', badge: null, 'priority': '1'},
            };

As you can notice some of the items have a property called parent that points to a parent key under which they will be nested.

Problem #1: Process this JSON and order it by priority. If an item has a parent key, create a children key (for template recursion) in the parent item and put them under it. I think this can be done easily with recursion but I just can't figure out how to do it.

So when the code is correct, it should give out the following output:

var final = [
            {title: 'Dashboard', href: '/admin', icon: 'fa-home', badge: null, 'priority': '1', id: 'dashboard'},
            {title: 'Users', href: '/admin/users', icon: 'fa-user', 'priority': '2', id: 'users'},
            {
                title: 'Expert users', href: '', icon: 'fa-cog', 'priority': '3', id: 'expert',
                children: [
                    { title: 'Site config', href: '/admin/config', icon: 'fa-cog', 'priority': '1', id: 'config',
                        children: [{title: 'Security settings', href: '/admin/security', icon: 'fa-key', 'priority': '1', id: 'security'}]
                    },
                    {title: 'Social logins', href: '/admin/social-logins', icon: 'fa-lock', 'priority': '2', id: 'logins'}
                ]
            },
            {title: 'Deploy', href: '/admin/deploy', icon: 'fa-upload', badge: null, id: 'deploy'}
            ]

Problem #2: Solved. Render this using AngularJS template recursion. I think I have figured this one using the examples. Here is my attempt to render it. The menu is rendering quite perfectly when the data is in the correct format.

Just need help with Problem #1. Create the final var from menu var (using recursion I guess).

1
  • P.S. I'm quite okay with using underscore or jquery (if it helps reduce the code size) Commented May 7, 2016 at 12:59

1 Answer 1

1

Try this: (By the way, the result of the example JSON is not the var final code you posted, since 'Deploy' has higher priority then 'User' and is on the same level (no parent). Also 'Expert User' has no parent 'User'.) Also no recursion is needed, iterative code will work just fine and it's faster.

var menu = {
            'users': {title: 'Users', href: '/admin/users', icon: 'fa-user', 'priority': '2'},
            'dashboard': {title: 'Dashboard', href: '/admin', icon: 'fa-home', badge: null, 'priority': '1'},
            'expert': {title: 'Expert users', href: '', icon: 'fa-cog', 'priority': '3'},
            'logins': {title: 'Social logins', href: '/admin/social-logins', icon: 'fa-lock', 'priority': '2', parent: 'expert'},
            'config': {title: 'Site config', href: '/admin/config', icon: 'fa-cog', 'priority': '1', parent: 'expert'},
            'security': {title: 'Site config', href: '/admin/config', icon: 'fa-key', 'priority': '1', parent: 'config'},
            'deploy': {title: 'Deploy', href: '/admin/deploy', icon: 'fa-upload', badge: null, 'priority': '1'},
            };
  
function insertAccordingToPriority(element, array){
     var index = 0;
     while(array.length > index && array[index].priority <= element.priority){
          index += 1;
     }
     array.splice(index, 0, element);
}

function createFinal(original){
  var final = [];
  for(var i in original){
     original[i].id = i;
     if(original[i].parent && original[original[i].parent]){
        if(!original[original[i].parent].children) original[original[i].parent].children = [];
     	insertAccordingToPriority(original[i], original[original[i].parent].children);
     }else insertAccordingToPriority(original[i], final);
  }
  return final;
}

var result = createFinal(menu);
console.log(result);

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.