4

I have the following code:

for (_field in _fields) {
    $.post(
        '/api/fields',
        { id: _field.id },
        function(data, _field) {
            alert(data);
        } (data, _fields[_field)
    );
}

I have to pass the _fields[_field] element to the function that returns the data from the jQuery because loses the reference to the right object during the loop. The problem is that in defining that the post function should have a _field parameter, you also have to specify a parameter for data, or data will be overwritten with _field.

Currently data returns as undefined because I have no data object defined inside the loop. I also tried passing in null, but that also just returns null. I'm looking for a way to pass the element without overwriting the data returned from the post function.

Is there any way to fix this, or is there perhaps an alternative jQuery method that can do what's needed?

1 Answer 1

7

You want a function factory function — a function that creates a function:

for (_fieldName in _fields) {
    $.post('/api/fields',
    {
        // Unrelated, but I think this bit is wrong; shouldn't it be
        // `id: _fields[_fieldName].id` ? You're trying to use `.id` on
        // a string -- see below for a full update
        id: _fieldName.id
    },
    makeHandler(_fields[_fieldName])
    );
}
function makeHandler(field) {
    return function(data) {
        // Use `data` and `field` here
    };
}

Note that in the object initializer we're passing into $.post, we're calling makeHandler to it runs and returns the function we'll then pass into $.post. That function is then called when the $.post completes, and has access to the data argument that $.post gives it as well as the field argument to makeHandler, because it's a closure over the context of the call to makeHandler, which includes the field argument. More: Closures are not complicated


Note that in the code above, I changed your variable _field to _fieldName to be more clear: The variable in for..in loops is a string, the name of a property. See also the comment, I think you were trying to use .id in the wrong place. Here's what I think you really wanted:

for (_fieldName in _fields) {
    _field = _fields[_fieldName];
    $.post('/api/fields',
    {
        id: _field.id
    },
    makeHandler(_field)
    );
}
function makeHandler(field) {
    return function(data) {
        // Use `data` and `field` here
    };
}

Also note that if _fields is an array, you shouldn't use for..in on it without safeguards. More: Myths and realities of for..in

Sign up to request clarification or add additional context in comments.

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.