Reputation: 5558
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?
Upvotes: 4
Views: 818
Reputation: 1074949
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
Upvotes: 7