Javascript define Singleton with arguments as a Module












1















I am trying to define a Singleton in Javascript to be able to consume from different files.



class DataService {

constructor(options) {
this.models = options.models ;
this.data = {};
this.refresh();
}

refresh() {
Promise.all([
this.models.DATA.model.findAll({
raw: true,
attributes: ['key', 'value']
})
]).then(([data]) => {
this.data = this.parseData(data);
});
}

parseData(data) {
data.map(x => {
this.data[x.key] = JSON.parse(x.value);
});
return this.data;
}

}

module.exports = (options) => { return new DataService(options) };


I want to be able to import the module like this



const data = require('dataService')(options);

console.log('data.example', data.example);


I am not sure if it is possible to do this, since I am using async methods, and the data is not ready when I print the log.










share|improve this question

























  • what is SettingsService?

    – quirimmo
    Jan 3 at 1:07











  • @quirimmo thank you for reading, sorry, that was a mistake, I fixed

    – agusgambina
    Jan 3 at 1:08
















1















I am trying to define a Singleton in Javascript to be able to consume from different files.



class DataService {

constructor(options) {
this.models = options.models ;
this.data = {};
this.refresh();
}

refresh() {
Promise.all([
this.models.DATA.model.findAll({
raw: true,
attributes: ['key', 'value']
})
]).then(([data]) => {
this.data = this.parseData(data);
});
}

parseData(data) {
data.map(x => {
this.data[x.key] = JSON.parse(x.value);
});
return this.data;
}

}

module.exports = (options) => { return new DataService(options) };


I want to be able to import the module like this



const data = require('dataService')(options);

console.log('data.example', data.example);


I am not sure if it is possible to do this, since I am using async methods, and the data is not ready when I print the log.










share|improve this question

























  • what is SettingsService?

    – quirimmo
    Jan 3 at 1:07











  • @quirimmo thank you for reading, sorry, that was a mistake, I fixed

    – agusgambina
    Jan 3 at 1:08














1












1








1








I am trying to define a Singleton in Javascript to be able to consume from different files.



class DataService {

constructor(options) {
this.models = options.models ;
this.data = {};
this.refresh();
}

refresh() {
Promise.all([
this.models.DATA.model.findAll({
raw: true,
attributes: ['key', 'value']
})
]).then(([data]) => {
this.data = this.parseData(data);
});
}

parseData(data) {
data.map(x => {
this.data[x.key] = JSON.parse(x.value);
});
return this.data;
}

}

module.exports = (options) => { return new DataService(options) };


I want to be able to import the module like this



const data = require('dataService')(options);

console.log('data.example', data.example);


I am not sure if it is possible to do this, since I am using async methods, and the data is not ready when I print the log.










share|improve this question
















I am trying to define a Singleton in Javascript to be able to consume from different files.



class DataService {

constructor(options) {
this.models = options.models ;
this.data = {};
this.refresh();
}

refresh() {
Promise.all([
this.models.DATA.model.findAll({
raw: true,
attributes: ['key', 'value']
})
]).then(([data]) => {
this.data = this.parseData(data);
});
}

parseData(data) {
data.map(x => {
this.data[x.key] = JSON.parse(x.value);
});
return this.data;
}

}

module.exports = (options) => { return new DataService(options) };


I want to be able to import the module like this



const data = require('dataService')(options);

console.log('data.example', data.example);


I am not sure if it is possible to do this, since I am using async methods, and the data is not ready when I print the log.







javascript






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 3 at 1:08







agusgambina

















asked Jan 3 at 0:59









agusgambinaagusgambina

2,28483957




2,28483957













  • what is SettingsService?

    – quirimmo
    Jan 3 at 1:07











  • @quirimmo thank you for reading, sorry, that was a mistake, I fixed

    – agusgambina
    Jan 3 at 1:08



















  • what is SettingsService?

    – quirimmo
    Jan 3 at 1:07











  • @quirimmo thank you for reading, sorry, that was a mistake, I fixed

    – agusgambina
    Jan 3 at 1:08

















what is SettingsService?

– quirimmo
Jan 3 at 1:07





what is SettingsService?

– quirimmo
Jan 3 at 1:07













@quirimmo thank you for reading, sorry, that was a mistake, I fixed

– agusgambina
Jan 3 at 1:08





@quirimmo thank you for reading, sorry, that was a mistake, I fixed

– agusgambina
Jan 3 at 1:08












2 Answers
2






active

oldest

votes


















1














The way in which you can leverage modules to achieve a singleton-like pattern across all modules is to export an instance directly.



The reason this works is that require caches the exports after the first import and thus will return that instance on all subsequent imports.



Right now you're exporting a function which, although it will always be the same function, has capabilities to always instantiate a new instance of your class and thus is breaking the singleton-pattern constraint you want to achieve (single instance across modules)



Because you want to externally specify the singleton instantiation options, one way you can do this with minimal changes to your code is to have the exported function return an instance if it already exists, rather than instantiate a new one:



let instance; // all files will receive this instance
module.exports = (options) => {
if (!instance) {
// only the first call to require will use these options to create an instance
instance = new DataService(options);
}
return instance;
}


This means that all files that do require('dataService')(options) will receive the same instance and whichever file imports the module first is who's instantiation options will apply.



Do note that all subsequent calls will still have to be of the form require('dataService')() (notice the extra invocation) which seems like a code-smell and would make the code harder to understand.



To make the code more readable, we could add some verboseness:



let instance; // all files will receive this instance
module.exports = {
getInstance(options) {
if (!instance) {
// only the first call to getInstance will use these options to create an instance
instance = new DataService(options);
}
return instance;
}
}


Which would be used like:



const instance = require('dataService').getInstance(options);
const instance = require('dataService').getInstance();
const instance = require('dataService').getInstance();


Another step could be to make the code more resilient to abuse by telling the programmer at run-time if they are using the API wrongly:



if (!instance) {
instance = new DataService(options);
} else if (options) {
// throw error on all subsequent calls with an options arg `require('dataService')(options)`
throw Error('Instance is already instantiate with `options`')
}
return instance;


This won't make the code more readable but would make it a bit safer.



If we interpret your API to mean "anytime options are passed, we should instantiate a new singleton", then you can consider maintaining a collection of instances instead, retrievable by some id (or maybe even the memory reference of the options themselves):



let instances = new Map();
module.exports = (options) => {
if (!instances.has(options.id)) {
instances.set(options.id) = new DataService(options);
}
return instances.get(options.id);
}




The fact that you have async code in your singleton shouldn't matter. Time is not a property of a singleton, the requirement is to only have a single instance.



That being said, you might want to consider actually returning the promises created in your methods so that you can properly chain them or await on them:



class DataService {

constructor(options) {
this.models = options.models ;
this.data = {};
this.refresh();
}

refresh() {
return Promise.all(/* ... */).then(/* ... */);
//^^^^^^ return the promise chain so we can react to it externally
}

// ...

}

(async () => {
await new DataService().refresh(); // now you can do this
})()





share|improve this answer


























  • This is a good answer but there should probably not be an options argument in this case or you should have one instance per options object. Like a Set<options, DataService>

    – justin.m.chase
    Jan 3 at 1:13











  • @justin.m.chase agreed, it's a bit confusing that the 2nd call to require('x')(options) will just ignore the options

    – nem035
    Jan 3 at 1:15











  • @nem035 thank you for the answer. The explanation helped a lot! now I am trying to figure out the last details.

    – agusgambina
    Jan 3 at 2:54











  • @agusgambina glad to help :)

    – nem035
    Jan 3 at 14:36



















2














That's how you can implement the Singleton with ES6:






class Singl {

constructor(options) {
console.log('calling constructor');
}

static getInstance(options) {
if (!Singl.instance) {
Singl.instance = new Singl(options);
}
return Singl.instance;
}
}

// the constructor will be called only once
Singl.getInstance();
Singl.getInstance();
Singl.getInstance();





As you can see from the snippet, the constructor will be called just the first time you call getInstance.



Then you should be able to export the getInstance method and pass options:



module.exports = Singl.getInstance;





share|improve this answer
























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54015088%2fjavascript-define-singleton-with-arguments-as-a-module%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    The way in which you can leverage modules to achieve a singleton-like pattern across all modules is to export an instance directly.



    The reason this works is that require caches the exports after the first import and thus will return that instance on all subsequent imports.



    Right now you're exporting a function which, although it will always be the same function, has capabilities to always instantiate a new instance of your class and thus is breaking the singleton-pattern constraint you want to achieve (single instance across modules)



    Because you want to externally specify the singleton instantiation options, one way you can do this with minimal changes to your code is to have the exported function return an instance if it already exists, rather than instantiate a new one:



    let instance; // all files will receive this instance
    module.exports = (options) => {
    if (!instance) {
    // only the first call to require will use these options to create an instance
    instance = new DataService(options);
    }
    return instance;
    }


    This means that all files that do require('dataService')(options) will receive the same instance and whichever file imports the module first is who's instantiation options will apply.



    Do note that all subsequent calls will still have to be of the form require('dataService')() (notice the extra invocation) which seems like a code-smell and would make the code harder to understand.



    To make the code more readable, we could add some verboseness:



    let instance; // all files will receive this instance
    module.exports = {
    getInstance(options) {
    if (!instance) {
    // only the first call to getInstance will use these options to create an instance
    instance = new DataService(options);
    }
    return instance;
    }
    }


    Which would be used like:



    const instance = require('dataService').getInstance(options);
    const instance = require('dataService').getInstance();
    const instance = require('dataService').getInstance();


    Another step could be to make the code more resilient to abuse by telling the programmer at run-time if they are using the API wrongly:



    if (!instance) {
    instance = new DataService(options);
    } else if (options) {
    // throw error on all subsequent calls with an options arg `require('dataService')(options)`
    throw Error('Instance is already instantiate with `options`')
    }
    return instance;


    This won't make the code more readable but would make it a bit safer.



    If we interpret your API to mean "anytime options are passed, we should instantiate a new singleton", then you can consider maintaining a collection of instances instead, retrievable by some id (or maybe even the memory reference of the options themselves):



    let instances = new Map();
    module.exports = (options) => {
    if (!instances.has(options.id)) {
    instances.set(options.id) = new DataService(options);
    }
    return instances.get(options.id);
    }




    The fact that you have async code in your singleton shouldn't matter. Time is not a property of a singleton, the requirement is to only have a single instance.



    That being said, you might want to consider actually returning the promises created in your methods so that you can properly chain them or await on them:



    class DataService {

    constructor(options) {
    this.models = options.models ;
    this.data = {};
    this.refresh();
    }

    refresh() {
    return Promise.all(/* ... */).then(/* ... */);
    //^^^^^^ return the promise chain so we can react to it externally
    }

    // ...

    }

    (async () => {
    await new DataService().refresh(); // now you can do this
    })()





    share|improve this answer


























    • This is a good answer but there should probably not be an options argument in this case or you should have one instance per options object. Like a Set<options, DataService>

      – justin.m.chase
      Jan 3 at 1:13











    • @justin.m.chase agreed, it's a bit confusing that the 2nd call to require('x')(options) will just ignore the options

      – nem035
      Jan 3 at 1:15











    • @nem035 thank you for the answer. The explanation helped a lot! now I am trying to figure out the last details.

      – agusgambina
      Jan 3 at 2:54











    • @agusgambina glad to help :)

      – nem035
      Jan 3 at 14:36
















    1














    The way in which you can leverage modules to achieve a singleton-like pattern across all modules is to export an instance directly.



    The reason this works is that require caches the exports after the first import and thus will return that instance on all subsequent imports.



    Right now you're exporting a function which, although it will always be the same function, has capabilities to always instantiate a new instance of your class and thus is breaking the singleton-pattern constraint you want to achieve (single instance across modules)



    Because you want to externally specify the singleton instantiation options, one way you can do this with minimal changes to your code is to have the exported function return an instance if it already exists, rather than instantiate a new one:



    let instance; // all files will receive this instance
    module.exports = (options) => {
    if (!instance) {
    // only the first call to require will use these options to create an instance
    instance = new DataService(options);
    }
    return instance;
    }


    This means that all files that do require('dataService')(options) will receive the same instance and whichever file imports the module first is who's instantiation options will apply.



    Do note that all subsequent calls will still have to be of the form require('dataService')() (notice the extra invocation) which seems like a code-smell and would make the code harder to understand.



    To make the code more readable, we could add some verboseness:



    let instance; // all files will receive this instance
    module.exports = {
    getInstance(options) {
    if (!instance) {
    // only the first call to getInstance will use these options to create an instance
    instance = new DataService(options);
    }
    return instance;
    }
    }


    Which would be used like:



    const instance = require('dataService').getInstance(options);
    const instance = require('dataService').getInstance();
    const instance = require('dataService').getInstance();


    Another step could be to make the code more resilient to abuse by telling the programmer at run-time if they are using the API wrongly:



    if (!instance) {
    instance = new DataService(options);
    } else if (options) {
    // throw error on all subsequent calls with an options arg `require('dataService')(options)`
    throw Error('Instance is already instantiate with `options`')
    }
    return instance;


    This won't make the code more readable but would make it a bit safer.



    If we interpret your API to mean "anytime options are passed, we should instantiate a new singleton", then you can consider maintaining a collection of instances instead, retrievable by some id (or maybe even the memory reference of the options themselves):



    let instances = new Map();
    module.exports = (options) => {
    if (!instances.has(options.id)) {
    instances.set(options.id) = new DataService(options);
    }
    return instances.get(options.id);
    }




    The fact that you have async code in your singleton shouldn't matter. Time is not a property of a singleton, the requirement is to only have a single instance.



    That being said, you might want to consider actually returning the promises created in your methods so that you can properly chain them or await on them:



    class DataService {

    constructor(options) {
    this.models = options.models ;
    this.data = {};
    this.refresh();
    }

    refresh() {
    return Promise.all(/* ... */).then(/* ... */);
    //^^^^^^ return the promise chain so we can react to it externally
    }

    // ...

    }

    (async () => {
    await new DataService().refresh(); // now you can do this
    })()





    share|improve this answer


























    • This is a good answer but there should probably not be an options argument in this case or you should have one instance per options object. Like a Set<options, DataService>

      – justin.m.chase
      Jan 3 at 1:13











    • @justin.m.chase agreed, it's a bit confusing that the 2nd call to require('x')(options) will just ignore the options

      – nem035
      Jan 3 at 1:15











    • @nem035 thank you for the answer. The explanation helped a lot! now I am trying to figure out the last details.

      – agusgambina
      Jan 3 at 2:54











    • @agusgambina glad to help :)

      – nem035
      Jan 3 at 14:36














    1












    1








    1







    The way in which you can leverage modules to achieve a singleton-like pattern across all modules is to export an instance directly.



    The reason this works is that require caches the exports after the first import and thus will return that instance on all subsequent imports.



    Right now you're exporting a function which, although it will always be the same function, has capabilities to always instantiate a new instance of your class and thus is breaking the singleton-pattern constraint you want to achieve (single instance across modules)



    Because you want to externally specify the singleton instantiation options, one way you can do this with minimal changes to your code is to have the exported function return an instance if it already exists, rather than instantiate a new one:



    let instance; // all files will receive this instance
    module.exports = (options) => {
    if (!instance) {
    // only the first call to require will use these options to create an instance
    instance = new DataService(options);
    }
    return instance;
    }


    This means that all files that do require('dataService')(options) will receive the same instance and whichever file imports the module first is who's instantiation options will apply.



    Do note that all subsequent calls will still have to be of the form require('dataService')() (notice the extra invocation) which seems like a code-smell and would make the code harder to understand.



    To make the code more readable, we could add some verboseness:



    let instance; // all files will receive this instance
    module.exports = {
    getInstance(options) {
    if (!instance) {
    // only the first call to getInstance will use these options to create an instance
    instance = new DataService(options);
    }
    return instance;
    }
    }


    Which would be used like:



    const instance = require('dataService').getInstance(options);
    const instance = require('dataService').getInstance();
    const instance = require('dataService').getInstance();


    Another step could be to make the code more resilient to abuse by telling the programmer at run-time if they are using the API wrongly:



    if (!instance) {
    instance = new DataService(options);
    } else if (options) {
    // throw error on all subsequent calls with an options arg `require('dataService')(options)`
    throw Error('Instance is already instantiate with `options`')
    }
    return instance;


    This won't make the code more readable but would make it a bit safer.



    If we interpret your API to mean "anytime options are passed, we should instantiate a new singleton", then you can consider maintaining a collection of instances instead, retrievable by some id (or maybe even the memory reference of the options themselves):



    let instances = new Map();
    module.exports = (options) => {
    if (!instances.has(options.id)) {
    instances.set(options.id) = new DataService(options);
    }
    return instances.get(options.id);
    }




    The fact that you have async code in your singleton shouldn't matter. Time is not a property of a singleton, the requirement is to only have a single instance.



    That being said, you might want to consider actually returning the promises created in your methods so that you can properly chain them or await on them:



    class DataService {

    constructor(options) {
    this.models = options.models ;
    this.data = {};
    this.refresh();
    }

    refresh() {
    return Promise.all(/* ... */).then(/* ... */);
    //^^^^^^ return the promise chain so we can react to it externally
    }

    // ...

    }

    (async () => {
    await new DataService().refresh(); // now you can do this
    })()





    share|improve this answer















    The way in which you can leverage modules to achieve a singleton-like pattern across all modules is to export an instance directly.



    The reason this works is that require caches the exports after the first import and thus will return that instance on all subsequent imports.



    Right now you're exporting a function which, although it will always be the same function, has capabilities to always instantiate a new instance of your class and thus is breaking the singleton-pattern constraint you want to achieve (single instance across modules)



    Because you want to externally specify the singleton instantiation options, one way you can do this with minimal changes to your code is to have the exported function return an instance if it already exists, rather than instantiate a new one:



    let instance; // all files will receive this instance
    module.exports = (options) => {
    if (!instance) {
    // only the first call to require will use these options to create an instance
    instance = new DataService(options);
    }
    return instance;
    }


    This means that all files that do require('dataService')(options) will receive the same instance and whichever file imports the module first is who's instantiation options will apply.



    Do note that all subsequent calls will still have to be of the form require('dataService')() (notice the extra invocation) which seems like a code-smell and would make the code harder to understand.



    To make the code more readable, we could add some verboseness:



    let instance; // all files will receive this instance
    module.exports = {
    getInstance(options) {
    if (!instance) {
    // only the first call to getInstance will use these options to create an instance
    instance = new DataService(options);
    }
    return instance;
    }
    }


    Which would be used like:



    const instance = require('dataService').getInstance(options);
    const instance = require('dataService').getInstance();
    const instance = require('dataService').getInstance();


    Another step could be to make the code more resilient to abuse by telling the programmer at run-time if they are using the API wrongly:



    if (!instance) {
    instance = new DataService(options);
    } else if (options) {
    // throw error on all subsequent calls with an options arg `require('dataService')(options)`
    throw Error('Instance is already instantiate with `options`')
    }
    return instance;


    This won't make the code more readable but would make it a bit safer.



    If we interpret your API to mean "anytime options are passed, we should instantiate a new singleton", then you can consider maintaining a collection of instances instead, retrievable by some id (or maybe even the memory reference of the options themselves):



    let instances = new Map();
    module.exports = (options) => {
    if (!instances.has(options.id)) {
    instances.set(options.id) = new DataService(options);
    }
    return instances.get(options.id);
    }




    The fact that you have async code in your singleton shouldn't matter. Time is not a property of a singleton, the requirement is to only have a single instance.



    That being said, you might want to consider actually returning the promises created in your methods so that you can properly chain them or await on them:



    class DataService {

    constructor(options) {
    this.models = options.models ;
    this.data = {};
    this.refresh();
    }

    refresh() {
    return Promise.all(/* ... */).then(/* ... */);
    //^^^^^^ return the promise chain so we can react to it externally
    }

    // ...

    }

    (async () => {
    await new DataService().refresh(); // now you can do this
    })()






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 3 at 1:35

























    answered Jan 3 at 1:09









    nem035nem035

    25.7k54164




    25.7k54164













    • This is a good answer but there should probably not be an options argument in this case or you should have one instance per options object. Like a Set<options, DataService>

      – justin.m.chase
      Jan 3 at 1:13











    • @justin.m.chase agreed, it's a bit confusing that the 2nd call to require('x')(options) will just ignore the options

      – nem035
      Jan 3 at 1:15











    • @nem035 thank you for the answer. The explanation helped a lot! now I am trying to figure out the last details.

      – agusgambina
      Jan 3 at 2:54











    • @agusgambina glad to help :)

      – nem035
      Jan 3 at 14:36



















    • This is a good answer but there should probably not be an options argument in this case or you should have one instance per options object. Like a Set<options, DataService>

      – justin.m.chase
      Jan 3 at 1:13











    • @justin.m.chase agreed, it's a bit confusing that the 2nd call to require('x')(options) will just ignore the options

      – nem035
      Jan 3 at 1:15











    • @nem035 thank you for the answer. The explanation helped a lot! now I am trying to figure out the last details.

      – agusgambina
      Jan 3 at 2:54











    • @agusgambina glad to help :)

      – nem035
      Jan 3 at 14:36

















    This is a good answer but there should probably not be an options argument in this case or you should have one instance per options object. Like a Set<options, DataService>

    – justin.m.chase
    Jan 3 at 1:13





    This is a good answer but there should probably not be an options argument in this case or you should have one instance per options object. Like a Set<options, DataService>

    – justin.m.chase
    Jan 3 at 1:13













    @justin.m.chase agreed, it's a bit confusing that the 2nd call to require('x')(options) will just ignore the options

    – nem035
    Jan 3 at 1:15





    @justin.m.chase agreed, it's a bit confusing that the 2nd call to require('x')(options) will just ignore the options

    – nem035
    Jan 3 at 1:15













    @nem035 thank you for the answer. The explanation helped a lot! now I am trying to figure out the last details.

    – agusgambina
    Jan 3 at 2:54





    @nem035 thank you for the answer. The explanation helped a lot! now I am trying to figure out the last details.

    – agusgambina
    Jan 3 at 2:54













    @agusgambina glad to help :)

    – nem035
    Jan 3 at 14:36





    @agusgambina glad to help :)

    – nem035
    Jan 3 at 14:36













    2














    That's how you can implement the Singleton with ES6:






    class Singl {

    constructor(options) {
    console.log('calling constructor');
    }

    static getInstance(options) {
    if (!Singl.instance) {
    Singl.instance = new Singl(options);
    }
    return Singl.instance;
    }
    }

    // the constructor will be called only once
    Singl.getInstance();
    Singl.getInstance();
    Singl.getInstance();





    As you can see from the snippet, the constructor will be called just the first time you call getInstance.



    Then you should be able to export the getInstance method and pass options:



    module.exports = Singl.getInstance;





    share|improve this answer




























      2














      That's how you can implement the Singleton with ES6:






      class Singl {

      constructor(options) {
      console.log('calling constructor');
      }

      static getInstance(options) {
      if (!Singl.instance) {
      Singl.instance = new Singl(options);
      }
      return Singl.instance;
      }
      }

      // the constructor will be called only once
      Singl.getInstance();
      Singl.getInstance();
      Singl.getInstance();





      As you can see from the snippet, the constructor will be called just the first time you call getInstance.



      Then you should be able to export the getInstance method and pass options:



      module.exports = Singl.getInstance;





      share|improve this answer


























        2












        2








        2







        That's how you can implement the Singleton with ES6:






        class Singl {

        constructor(options) {
        console.log('calling constructor');
        }

        static getInstance(options) {
        if (!Singl.instance) {
        Singl.instance = new Singl(options);
        }
        return Singl.instance;
        }
        }

        // the constructor will be called only once
        Singl.getInstance();
        Singl.getInstance();
        Singl.getInstance();





        As you can see from the snippet, the constructor will be called just the first time you call getInstance.



        Then you should be able to export the getInstance method and pass options:



        module.exports = Singl.getInstance;





        share|improve this answer













        That's how you can implement the Singleton with ES6:






        class Singl {

        constructor(options) {
        console.log('calling constructor');
        }

        static getInstance(options) {
        if (!Singl.instance) {
        Singl.instance = new Singl(options);
        }
        return Singl.instance;
        }
        }

        // the constructor will be called only once
        Singl.getInstance();
        Singl.getInstance();
        Singl.getInstance();





        As you can see from the snippet, the constructor will be called just the first time you call getInstance.



        Then you should be able to export the getInstance method and pass options:



        module.exports = Singl.getInstance;





        class Singl {

        constructor(options) {
        console.log('calling constructor');
        }

        static getInstance(options) {
        if (!Singl.instance) {
        Singl.instance = new Singl(options);
        }
        return Singl.instance;
        }
        }

        // the constructor will be called only once
        Singl.getInstance();
        Singl.getInstance();
        Singl.getInstance();





        class Singl {

        constructor(options) {
        console.log('calling constructor');
        }

        static getInstance(options) {
        if (!Singl.instance) {
        Singl.instance = new Singl(options);
        }
        return Singl.instance;
        }
        }

        // the constructor will be called only once
        Singl.getInstance();
        Singl.getInstance();
        Singl.getInstance();






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 3 at 1:10









        quirimmoquirimmo

        7,71811536




        7,71811536






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54015088%2fjavascript-define-singleton-with-arguments-as-a-module%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

            Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

            A Topological Invariant for $pi_3(U(n))$