0

I am attaching a callback function to select box on change event like this

select.on('change', config, party.selectOne);

Here config is the parameter I am passing to call back function. Inside call back I could access config parameter.

But my issue is, inside callback, $(this) returns unexpected object other than select box object

party.selectOne= function(config) {
    // is the selectbox
    var selectbox = $(this);
    var api = selectbox.data('api');
}

So I am getting api as undefined. But this will work fine if I don't pass any parameter to call back. What is wrong with me?

Example :

<select data-api="{'name':'one','address':'address1'}">
    <option>one</option>
    <option>two</option>
</select>
Lelio Faieta
  • 6,457
  • 7
  • 40
  • 74
Pramil
  • 227
  • 4
  • 17
  • **Note:** This is **not** a duplicate of [*How to access the correct `this` inside a callback?*](http://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-context-inside-a-callback). The OP is expecting `this` within the callback to be the `select` element. – T.J. Crowder May 08 '19 at 14:39
  • 1
    Please update your question with a [mcve] demonstrating the problem, ideally a **runnable** one using Stack Snippets (the `[<>]` toolbar button; [here's how to do one](https://meta.stackoverflow.com/questions/358992/)). With what you have above, `this` within the call to `party.selectOne` should be the `select` on which you've registered the event handler. – T.J. Crowder May 08 '19 at 14:40
  • Show your html. Where does `select` come from? show a runnable example code, not just some out-of-context snippets. – arieljuod May 08 '19 at 14:45
  • 2
    Can't reproduce: https://jsfiddle.net/2bujykew/ – NullDev May 08 '19 at 14:48

3 Answers3

0

So I am getting api as undefined.

That means that these two things are true:

  1. The element the change occurred on (one of the elements in select as of your select.on call) has never had .data('api', something) called on it, and

  2. That element doesn't have a data-api attribute on it — or rather, it didn't as of the first time .data was used on it.

Or, it could mean that party.selectOne has been bound at some point in code you haven't shown.

(Remember that data is not an accessor for data-* attributes. It's both more and less than that.)

jQuery's set-based nature can trip you up. If you have multiple elements in select as of your select.on call, and you've only set the api data item (directly via .data, or indirectly through a data-api attribute) on one of them, then a change event on a different one of them may give undefined for .data('api'). jQuery's data cache is per-element, not per-set.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

Not this is undefined, but the return value of data() for "api" is.
Use attr() instead of data():

// To make this example work
var party = {};
var config = { foo: "bar" };
var select = $("select");
// ---

party.selectOne = function(config) {
    var selectbox = $(this);
    var api = selectbox.attr('data-api');
    
    console.log(api);
    console.log(config.data.foo);
}

select.on('change', config, party.selectOne);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<select data-api="{'name':'one','address':'address1'}">
<option>one</option>
<option>two</option>
</select>
NullDev
  • 6,739
  • 4
  • 30
  • 54
0

It is resolved. Here config parameter was of type Object. If we pass config parameter as string, it will be resolved. I think, if we pass config as object, $(this) will refer config, instead of referencing select box element

Pramil
  • 227
  • 4
  • 17
  • This is not correct. Please refer to [my answer](https://stackoverflow.com/a/56043823/7575111) where `config` is indeed an object. – NullDev May 09 '19 at 08:03