0

I've got a wrapper class (singleton) like so:

'use strict'

var _ = require('lodash')

var SDK = {
    isInitialized: false,
    isSharedInstance: true,
    initSharedInstance: function() {
        var args = Array.prototype.slice.call(arguments)
        var self = this
        if (self.isInitialized) {
            console.log('SDK shared instance is already initialized')
            return self
        }
        var SDKClient = require('./lib/client')
        console.log('parent', args)
        var client = Function.prototype.bind.apply(SDKClient, args)
        _.assign(self, client)
        Object.setPrototypeOf(self, new client())
        self.isInitialized = true
        self.isSharedInstance = true
        self.SDKQuery = require('./lib/query')
    }
}

SDK.init = SDK.initSharedInstance
module.exports = SDK

To an SDK client class:

'use strict'

var _ = require('lodash')

var defaultOptions = {
    baseUrl: 'url'
}

var UsergridClient = function() {
    var self = this

    self.isSharedInstance = false

    var args = Array.prototype.slice.call(arguments)
    console.log('child', args)
    var options = _.isPlainObject(args[0]) ? args[0] : {}
    if (args.length === 2) {
        self.orgId = args[0]
        self.containerId = args[1]
    }

    _.defaults(self, options, helpers.config, defaultOptions)

    return self
}

Using this suggestion, it look like I should be able to do:

var client = Function.prototype.bind.apply(SDKClient, args)
_.assign(self, client)
Object.setPrototypeOf(self, new client())

But for some reason when I log it out, you'll see:

SDK.init('org', 'container')

// parent [ 'org', 'container' ]
// child [ 'container' ]

What's stranger still, is that when I only pass one argument, child logs out as an empty array.

What's wrong with this solution? How can I correctly pass the complete args array to the singleton's initialization of the SDK client? My guess is that it's some missing (or extra) argument in the bind.apply() call, but I can't figure out what.

4
  • What is that _.assign(self, client) good for? Commented Mar 8, 2016 at 22:02
  • There's no reason to use self in that method. Just directly accessing this makes it much more clear what is happening in there. Commented Mar 8, 2016 at 22:04
  • Honestly, nothing other than to be able to check that SDK instanceof SDKClient == true Commented Mar 8, 2016 at 22:04
  • The Object.setPrototypeOf is all that is needed for instanceof to work. Commented Mar 8, 2016 at 22:05

2 Answers 2

1

The post you linked says that

new Something(a, b, c)

is equivalent to

new (Function.prototype.bind.apply(Something, [null, a, b, c]))

Notice the null! You still need to bind the function to something - something that will subsequently be ignored when the function is used with new, but something to pass nonetheless.

You should use

var args = [null];
args.push.apply(args, arguments);
Sign up to request clarification or add additional context in comments.

2 Comments

Ha, now I get it. Thanks! Ended up using var client = Function.prototype.bind.apply(SDKClient, args.unshift(null)) for conciseness.
@remus: unshift returns the length, not the array; you can't use that in an expression. I guess the way to go would be bind.apply(constructor, [null].concat(slice.call(arguments))), but that's ugly.
0

apply() using to pass args in array []. So to pass your args using apply() you need to put it in array.

apply(context,[arg1,arg2,...]

You can use call() - it is doing what you want to do.

call(context, arg1, arg2,...]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.