0

I want to pass hash (associative array, object) to the function in coffeescript, when default values in this hash are defined. Passing hash object to the function will merge these values with default. How can I implement it?

var uiDialog = function({url = 'secret', data = 'something'}) {
  /* body of the function */
};

uiDialog({data:null,method:'GET'}); /* result arguments are { url: secret, data: null, method: 'GET' } */
uiDialog({url:'myURL',method:'GET'}); /* result arguments are { url: 'myURL', data: 'something', method: 'GET' } */

2 Answers 2

1

if you have access to jQuery, try: $.extend({}, yourDefaultsOptions, functionOptions)

if you do not have you may try doing it manually. here is an example approach

defaults = { a: 1, b: 3 }
funcOpts = { a: 2 }
final    = {}

for key, value of defaults
  final[key] = value

for key, value of funcOpts
  final[key] = value

console.log(defaults)
console.log(funcOpts)
console.log(final)
Sign up to request clarification or add additional context in comments.

Comments

1

The Problem

The problem is that Coffeescript supports default function parameters and destructuring assignment, but not at the same time. The simplest solution that permits more code reuse and more complex structures is to let coffeescript do the destructuring, and take on the task of handling default parameters yourself. Fortunately, that's pretty easy, thanks to jQuery's extend (first solution) or with polyfills for that method (second solution).

jQuery Solution

I've taken the liberty of rewriting your code a little, and I've built a working JSFiddle for your convenience: http://jsfiddle.net/scarl3tt/jkLjxyqe/

do ->
    class UiDialog
        _default =
            url: 'secret'
            data: 'something'
        constructor: (options) ->
            {@url, @data, @method} = $.extend({}, _default, options)

    dlg1 = new UiDialog
        data: null
        method:'GET' # result arguments are { url: secret, data: null, method: 'GET' }
    dlg2 = new UiDialog
        url: 'myURL'
        method: 'GET' # result arguments are { url: 'myURL', data: 'something', method: 'GET' }
        
    $('body').append("<div><h1>dlg1</h1><pre>#{JSON.stringify dlg1}</pre>")
    $('body').append("<div><h1>dlg2</h1><pre>#{JSON.stringify dlg2}</pre>")
    return

Vanilla JS Solution

Acknowledging, however, that jQuery does not belong in every project, a good solution is to define a method that does the same thing. I've supplied one in this second example that is a coffeescript port of a common extend polyfill. It's not the most efficient, but it has brevity: http://jsfiddle.net/scarl3tt/uq4tu6y1/

do (w=window) ->
    utils = (w.utils = w.utils || {})
    utils.extend = (target, others...) ->
        for source in others
            for name in Object.getOwnPropertyNames(source)
                target[name] = source[name]
        return target
    
    class UiDialog
        _default =
            url: 'secret'
            data: 'something'
        constructor: (options) ->
            {@url, @data, @method} = utils.extend({}, _default, options)

    dlg1 = new UiDialog
        data: null
        method:'GET' # result arguments are { url: secret, data: null, method: 'GET' }
    dlg2 = new UiDialog
        url: 'myURL'
        method: 'GET' # result arguments are { url: 'myURL', data: 'something', method: 'GET' }
        
    $('body').append("<div><h1>dlg1</h1><pre>#{JSON.stringify dlg1}</pre>")
    $('body').append("<div><h1>dlg2</h1><pre>#{JSON.stringify dlg2}</pre>")
    return

Note that my vanilla solution does include and use jQuery, but this is solely for the ease of printing the results. It's not actually required to make it work.

Also - for clarity - I put my extend polyfill in the window.utils namespace rather than in window.$.

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.