0

I have 3 .js files. The main Home.js and two other .js files, for instance Page1.js, Page2.js

Home.js:

 var Home= {

            Sample: function (pageId,data) {

            pageId.MergePageData(data);
        }
    }

Page1.js:

var Page1 = {

    MergePageData: function (data) {
    // do something
   }
}

Page2.js:

var Page2 = {

    MergePageData: function (data) {
     // do something
   }
}

I tried calling like this by passing it as a string:

Home.Sample('Page1', 'data');

Home.Sample('Page2', 'data');

But I guess as it is being passed as a string am getting an error

"Object doesn't support property or method 'MergePageData' "

I need to differentiate the call between the two functions in two different js files. How to achieve that?

Hasib Tarafder
  • 5,773
  • 3
  • 30
  • 44
Xavier
  • 1,672
  • 5
  • 27
  • 46

2 Answers2

1

The pageId in your function is just a variable, and when you call it you specify the type of this variable, and as you pass "Page1", which is a String it is just a string without having anything to do with your real Page1 object. but there are some options that can help you out.

The Other point that you have to consider is, it doesn't matter you have 2 or 3 different js files. the important point is if all your javascript codes are injected to single html page, then you can have all your code in all the JavaScript files in single window context. So if you define something in a global scope which is window, you can have access to it all over your JavaScript code.

It seems your Page1 and Page2 are global objects, so you can do it like:

var Home= {

        Sample: function (pageId,data) {

        window[pageId].MergePageData(data);
    }
}

but I guess data vriable is not a global, you have 2 options, first make it global or just store it in a storage like:

localStorage.setItem("data", JSON.stringify(data));

then change your Sample function like this:

var Home= {

        Sample: function (pageId,data) {

        window[pageId].MergePageData(JSON.parse(localStorage.getItem("data")));
    }
}

Although you have to be very careful about the size of your data object, if it is a big object with a lot of properties and inner objects, you should reconsider and change your solution.

Mehran Hatami
  • 12,723
  • 6
  • 28
  • 35
1

Basically you want to create your object Home inside an IIFE. That way you can pass in any library or object namespace throughout several files.

For your Home object, declare and run an anonymous function, assign your object directly to the the window object. This will be your "namespace" and accessible throughout your files by window.Home. Use this file to initialize your Page objects. As for now the DOM ready event is used from jQuery.

// @param ($): jquery library 1.10.2
(function ($) {

    // 1. ECMA-262/5
    'use strict';

    // 2. PRIVATE CONFIGURATION
    var cfg = {
        // an object literal to store config
        page2: {
            page: 'page2',
            data: 'data'
        }
    };

    // 3. GLOBAL OBJECT NAMESPACE
    window.Home = {
        init: function(){
            // initialize your other files
            this.cache = {
                page1: new Home.Sample();
                page2: new Home.Sample(cfg.page2); 
            }
        }
    };

    // 4. ONCE THE DOM IS READY
    $(function () {
        Home.init();
    });

}(window.jQuery));

Then for your other files, a slightly different approach can be used.

// @param ($): jquery library 1.10.2
// @param (home): Home namespace
window.Home = (function ($, home) {

    // 1. ECMA-262/5
    'use strict';

    // 2. CONFIGURATION
    var cfg = {
        page: 'page1'
        data: 'data'
    };

    // 3. CONSTRUCTOR FUNCTION
    home.Sample = function (options) {
        this.settings = $.extend({}, cfg, options);
        this.init();
    };

    // 4. PROTOTYPE OBJECT
    home.Sample.prototype = {
        init: function(){
            this.cacheItems();
            this.mergePageData(settings.data);
        },

        cacheItems: function(){
            this.page = settings.page;
        },

        mergePageData: function (data) {
            // do something with this.page and data
            // consider caching data instead of passing it along
        }
    };

    // 5. GLOBALIZE OBJECT
    return home;

}(window.jQuery, window.Home || {}));

This approach is modular and better to maintain. Since the whole configuration is extracted from the logic you will find it easier to create different instances of an object. Simply by passing in options into your Sample object you can change the whole data/structure but keeping behavior as intended. You can fill in options from your server language and use the sizzle selector engine inside jQuery todo powerful DOM traversing and so on ...

Tim Vermaelen
  • 6,869
  • 1
  • 25
  • 39