3

I have a dropdown working nice:

<select class="picker-select" data-bind="options: searchOptions, select:{}, optionsText: 'name', optionsValue: 'id', value: selectedSearchOption" ></select>

Now I want to execute a function when selection changes but it does not seem to work.


What I've tried:

onchange event:

onchange="actionWhenChange()"   // also tried without parenthesys

MODEL:

function actionWhenChange(event) {
  console.log("doing stuff");
};

ERROR:

Uncaught (in promise) ReferenceError: actionWhenChange is not defined


And with knockout event binding (also tried without parenthesys)

data-bind="event: { onchange: actionWhenChange() }, ... more bindings

MODEL:

self.actionWhenChange = function (event) {
  console.log("doing stuff");
}

But I get no error.

Any ideas?

joc
  • 1,336
  • 12
  • 31
  • 2
    Have a look at [this answer I wrote](https://stackoverflow.com/a/43158167/3297291). The question is formulated differently, but the answer is the same. – user3297291 Apr 04 '18 at 13:02
  • 1
    I.e.: in your model, you write: `self.selectedSearchOption.subscribe(self.actionWhenChange)` – user3297291 Apr 04 '18 at 13:05
  • 1
    @user3297291 I've fixed it using correct dom event... but I will try subscribe also just to see how it works, many thanks `:)` – joc Apr 04 '18 at 13:08

1 Answers1

3

Well, finally found out what's going on :)

First solution wasn't working because the function could not be found as it was inside the model. That's why undefined error.

About second option, the event binding, knockout is handling DOM events, and onchange is not one of the DOM events as can be found here.

So solution was just remove the on from onchange and use the change event:

data-bind="event: { change: actionWhenChange }, ... more bindings

BUT

The correct way to solve this is the stated by user3297291: use subscribe to value observable inside the model in this way:

self.selectedSearchOption.subscribe(self.actionWhenChange) – 

Hope this can help someone in the futue :)

joc
  • 1,336
  • 12
  • 31
  • 1
    While it's nice that you're sharing your solution, please have a look at the answer I linked in the comments. *Subscribing to the DOM's `change` event is an anti-pattern in knockout*. Subscribe to the observable instead. Also, you shouldn't call the method when passing it to the event binding: `event: { change: actionWhenChange }` is the correct syntax. – user3297291 Apr 04 '18 at 13:07
  • Thanks for your clarification, I'm trying subscribe option, one question.... why use change event is an anti pattern?? – joc Apr 04 '18 at 13:09
  • 1
    When using knockout, you only care about your view model. Syncing the values in your viewmodel with the DOM is knockout's job and happens through data-binds. Event bindings are only used to react to *user input*. If you want to react to a change, you listen to changes in your view model without caring where they come from. That way, if the values changes by *any* means, you ensure your action is always called. – user3297291 Apr 04 '18 at 13:12
  • 1
    @user3297291 subscribe is not only working, but far more elegant and readable. I've edited my answer, but feel free to post a new answer if you want me to accept it. Many thanks again `:)` – joc Apr 04 '18 at 13:49