Novice
Novice

Reputation: 478

Knockout fire subscription on load for drop down change

I have to use valueHasMutated method in ko to fire subscription on page load while binding Country list dropdown so that I can fetch state on the basis of selected dropdown, is there an alternative to this ? How can I fire the country subscription without using this method ?

Country List: <select id="CountryDropdownList" data-bind="options: viewModel.CountryCollection,optionsText:'CountryName',optionsValue:'CountryName',value:viewModel.SelectedCountry"></select>
State List: <select id="StateDropdownList" data-bind="options: viewModel.StateCollection,optionsText:'StateName',optionsValue:'StateName',value:viewModel.SelectedState"></select>

<script>
        var viewModel = ko.mapping.fromJS(@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model)));
        console.log(viewModel.SelectedState()); //State3 the initial value

        viewModel.SelectedCountry.subscribe(function (newSelectedCountry) {
            alert(newSelectedCountry);
            console.log(viewModel.SelectedState()); //undefined why?
            $.ajax({
                url: 'Home/GetStateList?Country=' + newSelectedCountry,
                success: function (data) {
                    viewModel.StateCollection(ko.mapping.fromJS(data)());
                    console.log(viewModel.SelectedState());  //state0 why?

                }
            })
        });


        ko.applyBindings(viewModel);
        $(function () {
           //to fire subscription
            viewModel.SelectedCountry.valueHasMutated();
        })

    </script>

Upvotes: 0

Views: 944

Answers (2)

Philip Bijker
Philip Bijker

Reputation: 5115

I guess that the problem is in attaching the event handler after the complete construction of the model object by calling fromJS. All observables do already have their values set, so the subscribed function is not called without the manual call to valueHasMutated.

A solution could be by

  • first creating the model, including the subscribe to the SelectedCountry observable.
  • instantiate this model and set the observable values

This way the subscribed function will be called, because the handler is attached before values are set.

Upvotes: 0

Roy J
Roy J

Reputation: 43881

Don't specify viewmodel.on your bind variables in the HTML. When you call ko.applyBindings, it creates the default context for your bind variables.

If the values of the value bound variable doesn't match any of the options values, it will (by default) be set to undefined. This may be what is happening (see your "undefined why?" comment). Try adding the valueAllowUnset option. I'm probably explaining this wrong. But you'll want to check the initial values against the options, at any rate.

Upvotes: 1

Related Questions