0

So I've created an angular js module and tried linking a service and using this service to share variables throughout the app. Everything is working fine but when I try to set the submenu[1] to a object it says submenu[1] is undefined. Which is correct it hasnt been created yet. But I just want to set the submenu[1] equal to an object. Don't see why it would have to be created. Not sure why its saying Uncaught TypeError: Cannot Read property submenu of undefined. I console.log the menuArray[key] I'm on and it comes back undefined. But that doesnt make sense either.


    setSubMenu : function(key, subKey, value){
                        console.log(sharedVariables.menuArray[key]);
                sharedVariables.menuArray[key].subMenu[subKey] = value;
    }

Here is what I have:

    var myModule = angular.module('companiesApp', ['ngResource']).config(function($routeProvider) {
    $routeProvider
        .when ('/', {controller:ListCtrl, template: $('#companies-list').html()})
        .when ('/new', {controller:NewCtrl, template: $('#companies-edit').html()})
        .when('/newMenu/:companyID', {controller:EditMenuCtrl, template: $('#menu-edit').html()})
        .when ('/edit/:companyID', {controller:EditCtrl, template: $('#companies-edit').html()})
        .when ('/editMenu/:companyID', {controller:EditMenuCtrl, template: $('#menu-edit').html()})
        .when ('/settings/:companyID', {controller:SettingsCtrl, template: $('#companies-settings').html()})});


myModule.service('sharedVariables', function(){
    var sharedVariables = { count : 0, originalCount : 0, menuArray : []};
    return{
        getOriginalCount : function(){
            return sharedVariables.originalCount;
        },
      setOriginalCount : function(value){
            sharedVariables.originalCount = value;
        },
        getCount : function(){
            return sharedVariables.count;
        },
        setCount : function(value){
            sharedVariables.count = value;
        },
        getMenu : function(){
            return sharedVariables.menuArray;
        },
        setMenu : function(key, value){
            sharedVariables.menuArray[key] = value;
        },
      setMenuName : function(key,value){
            sharedVariables.menuArray[key].name = value;
        },
        setMenuEndPos : function(key, posLeft, posTop){
            sharedVariables.menuArray[key].endPosLeft = posLeft;
            sharedVariables.menuArray[key].endPosTop = posTop;
        },
        setSubMenu : function(key, subKey, value){
            sharedVariables.menuArray[key].subMenu[subKey] = value;
        }
    };
});

function EditMenuCtrl($scope,$routeParams, $location, sharedVariables){
    var count = 0;
    $scope.companyID = $routeParams.companyID;
    $scope.menuArray = [];
    $.ajax({
        url : "companies.php",
        type : "post",
        data : {
            action : "getMenus",
            id : $routeParams.companyID
        },
        success : function(data,status){
          var responses = JSON.parse(data);
            $('#menu').empty();
            for(i in responses){
                //if the Root Order LI has not been created, create it
                if($('#li-' + responses[i].rootORDER).length == 0){
                    count++;
                    var html = '<li id="li-' + responses[i].rootORDER + '" class="dropdown">' + '<a id="link-' + responses[i].rootORDER;
                    html += '" role="button" class="dropdown-toggle" data-type="text" data-toggle="dropdown">' + responses[i].menuROOT;
                    html += '</a>' + '<ul id="ul-' + responses[i].rootORDER; 
                    html += '" class="dropdown-menu" role="menu" aria-labelledby="dLabel" ><li role="presentation"><a href="javascript:void(0)" onclick="addLITOUL()" role="menuitem"><i class="icon-plus-sign"></i></a></li></ul></li>';
                    $('#menu').append(html);
                    //Record the Start Position of the Element
                    var Start = $('#li-' + responses[i].rootORDER).position();
                    sharedVariables.setMenu(responses[i].rootOrder, {name : responses[i].menuROOT, startPosLeft : Start.left, startPosTop : Start.top, subMenu : []});
                    //Make the Title Editable
                    $('#link-' + responses[i].rootORDER).editable(function(value,settings){
                        var tempID = $(this).attr('id');
                        tempID = tempID.substring(5);
                        sharedVariables.setMenuName(tempID,value);
                        return(value);
                    });
                    //Make the DropDowns and make them draggable
                    $('.dropdown-toggle').dropdown();
                    $('.dropdown').draggable({
                        containment: "#container", 
                        scroll: false, 
                        snap: true,
                        stop: function(event, ui) {
                            var Stoppos = $(this).position();
                            $("#position").text("STOP: \nLeft: "+ Stoppos.left + "\nTop: " + Stoppos.top);
                            var tempID = $(this).attr("id");
                            tempID = tempID.substring(3); //remove li- to get the index into the array
                            sharedVariables.setMenuEndPos(tempID, Stoppos.left, Stoppos.top);
                        }
                    });
                }//end of if
            }//end of (for i in responses)
            sharedVariables.setOriginalCount(count);
            sharedVariables.setCount(count);
            //Fill in the inner UL with it's links
            for(i in responses){
                html = '<li id="' + i + '-' + responses[i].menuTITLE+ '" role="presentation"><a role="menuitem" href="javascript:void(0)">' + responses[i].menuTITLE + '</a>';
                html += '</li>';
                $('#ul-' + responses[i].rootORDER).append(html);
                sharedVariables.setSubMenu(responses[i].rootORDER, responses[i].linkORDER, {name: responses[i].menuTITLE});
            }
        }
    });
    console.log(sharedVariables.getOriginalCount());
}
Astrum
  • 31
  • 1
  • 4
  • 1
    Just a comment on your code - one of core tenets of Angular is don't manipulate the DOM from a controller. AngularJS is built to handle the DOM changes for you, so injecting a massive amount of HTML from the controller is a scary warning sign you're the wrong track. If you need to initialize jQuery widgets or perform other manipulation, take a look at building a custom Angular directive. – Mike Robinson Mar 07 '13 at 19:28
  • The reason I can't use angular to do it is because the response is i'm building a menu. So the root element of the menu contains sub menu's and the response is a json of the sub menus and what root menu they are tied too. So I can't handle this logic within an ng-repeat. So i have to generate the DOM in the controller. – Astrum Mar 07 '13 at 19:47
  • Read [How do I “think in AngularJS” if I have a jQuery background?](http://stackoverflow.com/questions/14994391/how-do-i-think-in-angularjs-if-i-have-a-jquery-background), and check out the "Common Pitfalls" section under [Angular FAQ](http://docs.angularjs.org/misc/faq). It'll save you from a lot of headache. – Stewie Mar 07 '13 at 20:35

1 Answers1

2

I dare say your problem has something to do with the fact that you are calling setMenu with the key responses[i].rootOrder and setSubMenu with the different key responses[i].rootORDER. Judging by the rest of your code, responses[i].rootOrder is probably undefined, which should be giving odd results elsewhere really...

Frances McMullin
  • 5,516
  • 2
  • 18
  • 19
  • You were right. Simple forgetting to caps rest of the word. Thanks. Now I feel really stupid haha. – Astrum Mar 07 '13 at 19:59