Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create multiple instances of IIFE Javascript module?

I'm dealing with a huge javascript codebase that I'm trying to reorganize. I'm not really an expert and I just started studying good javascript coding practices. So, one thing I'm trying to do is to divide all the code in modules. In this particular case I'm trying to create a module that would help me to optimize video embeds. I would like to pass the module an id and receive some html code or an image out of it.

I'm not putting the whole code here, but it's enough for the example:

var videoIframe = (function($) {
    'use strict';
     var id,

    setVideoId = function(videoId) {
        id = videoId;
        console.log(id);
    },
    getVideoThumbnail = function(videoId) {
        setVideoId(videoId);

    },
    test = function() {
        console.log(id)
    },
    getVideoEmbedCode = function() {

    };

    return {
       test: test,
       getVideoThumbnail: getVideoThumbnail
    };
})(jQuery);

In another module I assign it to two variables:

    var video1 = videoIframe;
    var video2 = videoIframe;

    video1.getVideoThumbnail(123);
    video2.getVideoThumbnail(456);

    video1.test();
    video2.test();

And, of course, I'm not getting what I expected. After the second getVideoThumbnail call, it always prints 456.

Doing some research I understood that I'm creating a singleton, a single instance, and I'm only changing values inside that instance. I think I need a constructor for my module, but I'm not sure how to create it in combination with the IIFE pattern. And is it the right approach?

like image 640
Carlo Avatar asked Jan 08 '23 09:01

Carlo


2 Answers

And is it the right approach?

No. IIFEs are for things you want to do exactly once.

If you want to do something multiple times, then use a regular function and call it multiple times.

var videoIframe = (function($) {

    function videoIframe() {
        'use strict';
        var id,

            setVideoId = function(videoId) {
                id = videoId;
                console.log(id);
            },
            getVideoThumbnail = function(videoId) {
                setVideoId(videoId);

            },
            test = function() {
                console.log(id)
            },
            getVideoEmbedCode = function() {

            };

        return {
            test: test,
            getVideoThumbnail: getVideoThumbnail
        };
    }

    return videoIframe;
})(jQuery);

var video1 = videoIframe();
var video2 = videoIframe();

video1.getVideoThumbnail(123);
video2.getVideoThumbnail(456);

video1.test();
video2.test();
like image 182
Quentin Avatar answered Jan 09 '23 22:01

Quentin


The problem is that you are initializing object when assigning to videoIframe variable:

var videoIframe = (function($) {
  // ...
})(jQuery);

You can try with:

var videoIframe = (function($) {
  // ...
});

var video1 = videoIframe(jQuery);
var video2 = videoIframe(jQuery);
like image 25
hsz Avatar answered Jan 09 '23 23:01

hsz