0

here is the code, I have a menu global variable inside the function. I want to use it outside it, but then I get an "undefined reference error...· This is the only javascript code I have, so there's no interference with another variables or functions.

Thanks in advance.

$(function() {
  menu =  $('nav#menu').mmenu(
    {   
      navbars: [
        {
          position: "top",  
          height    : 1,
          content : [ 
            '<a href="#/" class="fa fa-phone"></a>',
            '<img src="imagenes/wheel32.png" /><p class="navbartxt">bicimap.uy</p>',                    
          ]
        },
        {
          position: "bottom",
          content: [
            '<a class="fa fa-envelope"></a>',
            '<a class="fa fa-twitter"></a>',
            '<a class="fa fa-facebook"></a>'
          ]
        }
      ],                    
      extensions: ["multiline"],    
      onClick: {
        close: false
      },
      navbar:{
        title: "Inicio"                     
      },
      offCanvas: {           
        zposition : "next"
      }
    });         
  });

I need to put this inside the function to get it working

var API = $("#menu").data( "mmenu" );

menu.on( 'click', 'a[class^="fa fa-twitter"]', function() {  
  $('#twitter').show();                 
  var API = $("#menu").data( "mmenu" );
  API.close();      

  return false;
});
Matthew Herbst
  • 29,477
  • 23
  • 85
  • 128
rossig7
  • 81
  • 1
  • 10

3 Answers3

1

I'm lacking some context here (I'm assuming there's more we don't see?)

But you may be executing the latter snippet, menu.on( 'click'… before the code inside $(…) has run (on dom ready); so menu would be undefined.

If you're just getting started, it's worth looking into your browser's developer tools and learning about break points and logging.

You'll need to make sure that you use menu only after it's been set, likely by delaying all your invocation to be on ready.


Execution Order

  1. The $ is called and the function is provided as the first and only argument. The function itself is not called.

  2. API is defined by the result of $("#menu") This may or may not be found yet depending upon where in the html file you've added this script.

  3. The data method is invoked on the result of that

  4. You try to call on on menu, which is still undefined

  5. sometime later, the function you passed to $ is called, and menu ends up being defined, to late to be useful

mczepiel
  • 711
  • 3
  • 12
  • Indeed that's all as I said there isn't more code than the html, this is the unique javascript piece of code. Thanks that's what I was afraid of: it could be executing before the menu had been loaded. – rossig7 Jan 23 '16 at 00:31
  • There's nothing to be afraid of, just delay invoking code that expects `menu` to be defined until after you've defined it as you do within that function you're running after the DOM is ready. I'll add a quick note if you don't understand the execution order. – mczepiel Jan 23 '16 at 00:35
  • As a note for clarification: since there's no actual `var` declaration it's not just the _value_ of menu that wouldn't be defined, there would be no hoisted declaration at all, and there will be no reference to `menu` in existence; hence why you get an _"undefined reference"_ error as opposed to a _"trying to access a property on undefined"_ error. There really should be a declaration of `var menu;` in the global scope so that it hoists a declaration. – Jimbo Jonny Jan 23 '16 at 01:15
  • @mczepiel I can't get the delay working. I am tinkering on this. – rossig7 Jan 23 '16 at 05:51
  • Agreed, there _should_ be a `var menu` declaration in either the global or an equally useful scope, but simply adding that won't address the problem. It will resolve the exception, but then the value will still be undefined. – mczepiel Jan 27 '16 at 16:36
  • @rossig7 "Delay" is probably too loaded a term; you just need to order your code such that you don't try to use `menu` until after it's been declared and given the value you expect. This is most likely just a matter of moving that usage inside the same function you're passing to $ – mczepiel Jan 27 '16 at 16:38
0

If your closure/anonymous function is happening asynchonously, its possible that the work has not been done by the time the rest of your code is computed. I would need more context to determine that.

Cody
  • 1,389
  • 1
  • 9
  • 14
  • JavaScript will create global variables implicitly if you don't use `var` Though yes, this is frowned upon and the source of many bugs. – mczepiel Jan 23 '16 at 00:23
  • Did I get downvoted because I suggested a best practice? – Cody Jan 23 '16 at 00:24
  • Sorry, "For a variable to be global," was incorrect. But yes, you're right about it being a good idea. Your recent addition of the async actually addresses the issue though, upvoting. – mczepiel Jan 23 '16 at 00:27
  • I tryed it actuall but it didn't work, with menu = ' ' and menu = null – rossig7 Jan 23 '16 at 00:27
  • 1
    @rossig7 I believe the actual problem is due to the fact that your anonymous function, the $(function() { part, is happening asynchronously. Its not doing work in the same scope that the rest of your code is running, and is not available in the context you need it to be. – Cody Jan 23 '16 at 00:29
  • Maybe I have to put the code something like this:$.when(a()) .then(b); – rossig7 Jan 23 '16 at 00:37
  • @mczepiel - it will...but **only after that line of code has run**. Since there is no actual declaration, there is no hoisting. It only adds it as a LHS reference in the global scope once a line of code tries to use that LHS reference. – Jimbo Jonny Jan 23 '16 at 00:56
0

This is the solution I found, maybe it's not the best because it could bring problems. For some reason the ready function doesn't work as is shown above, maybe some assets are being expected.

menu = null;
$(function() {

            menu =  $('nav#menu').mmenu(

            {   
                navbars     : [{
                    position: "top",    
                    height  : 1,
                    content : [ 

                        '<img src="imagenes/wheel32.png" /><p class="navbartxt">bicimap.uy</p>',                

                    ]
                },
                {
                    position: "bottom",
                    content: [
                        '<a class="fa fa-envelope"></a>',
                        '<a class="fa fa-twitter"></a>',
                        '<a class="fa fa-facebook"></a>'
                    ]
                }
                ],                  
                extensions: ["multiline"],  
                 onClick: {
                    close: false
                 },
                navbar:{
                    title: "Inicio"                     
                },
                offCanvas: {
                  zposition : "next"
                }

        });

    });


$( window ).load(function() {

  var API = $("#menu").data( "mmenu" );

        menu.on( 'click', 'a[class^="fa fa-twitter"]', function() {  
                        $('#twitter').show();

                          var API = $("#menu").data( "mmenu" );
                          API.close();      

                        return false;
                    }
         );

});
rossig7
  • 81
  • 1
  • 10