javascriptrevealing-module-pattern

Revealing module pattern, undefined property


I have two files, app.js and utils.js that are concatenated together at build via Gulp.

I'm getting an error "Cannot read property 'getUrlParam' of undefined" when trying trying to set the app.mapYear value inside of my return statement.

Setting app.mapYear inside of the init function seems to work. I'm wondering why I'm unable to set app.mapYear in my return statement though.

Am I missing something simple here? Is there a better way? I'm hoping to prevent setting object properties sporadically throughout my code if I can do it in my return.

// app.js
//*****************
'use strict';

var app = app || {};
app = (function() {

    const getMapYear = () => {
        return app.utils.getUrlParam('year');
    };

    const mapYear = getMapYear();

    const init = () => {
        //init offcanvas menu
        $(document).foundation();

        // app.mapYear = mapYear();
    };

    return {
        init,
        mapYear
    };

})();

$(function() {
    app.init();
});


utils.js
//*****************

var app = app || {};

app.utils = (function() {

    const getUrlParam = () => {
        console.log(document.location.search);
        return document.location.search;
    }

    return {
        getUrlParam
    };

})();

Thanks for your time and suggestions!

EDIT: For anyone that's run into the same issue, here is how I resolved it given the responses provided.

When compiled, utils.js is first followed by app.js. My return statement in app.js looks like this:

return {
    init,
    utils: app.utils,
    mapYear: getMapYear()
};

Solution

  • In this order will work:

    //utils.js
    //*****************
    
    var app = app || {};
    
    app.utils = (function() {
    
      const getUrlParam = () => {
        console.log(document.location.search);
        return document.location.search;
      }
    
      return {
        getUrlParam
      };
    
    })();
    
    
    // app.js
    //*****************
    'use strict';
    //         |-- app contains the definition of (utils.js).
    var app = app || {};
    app = (function() {
    
      const getMapYear = () => {
        return app.utils.getUrlParam('year'); // You can use «app.utils».
      };
    
      const mapYear = getMapYear();
    
      const init = () => {
        //init offcanvas menu
        // $(document).foundation();
    
        // app.mapYear = mapYear();
      };
    
      return {
        init,
        mapYear,
        app
      };
    
    })();
    
    $(function() {
      app.init();
      console.log(app);
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

    enter image description here