Abhishek Jain
Abhishek Jain

Reputation: 315

knockoutjs using module pattern not working

I am trying to create simple knockout example using module pattern

var login = {}; //login namespace

//Constructor
login.UserData = function () {
    var self = this;
    self.UserName = ko.observable("");
    self.Password = ko.observable("");
};
//View-Model
login.UserVM = function () {
    this.userdata = new login.UserData(),
    this.apiUrl = 'http://localhost:9090/',
    this.authenticate = function () {
        var data = JSON.parse(ko.toJSON(this.userdata));
        var service = apiUrl + '/api/Cryptography/Encrypt';
        DBconnection.fetchdata('POST', service, JSON.stringify(data.Password), response, function () { console.log('Cannot fetch data') }, null, true);
        function response(res) {
            console.log(res)
        }
    }
    return {
        authenticate: this.authenticate
    }
}();

$(function () {
    ko.applyBindings(login.UserVM); /* Apply the Knockout Bindings */
});

HTML CODE:

<form id="loginform" name="loginForm" method="POST">
    <div id="form-root">
        <div>
            <label class="form-label">User Name:</label>
            <input type="text" id="txtFirstName" name="txtFirstName" data-bind="value:login.UserData.UserName" />
        </div>
        <div>
            <label class="form-label">Password:</label>
            <input type="text" id="txtLastName" name="txtLastName" data-bind="value:login.UserData.Password" />
        </div>
        <div>
            <input type="button" id="btnSubmit" value="Submit" data-bind="click: authenticate" />                
        </div>
    </div>
</form>

the problem is am not able to get userdata in the viewmodel on click of submit it is returning undefined and the login object holds the changed value of textbox but on click it is returning black values. please let me know

Also can you let me know how to implement definative module pattern in the same code.

Upvotes: 1

Views: 74

Answers (1)

adiga
adiga

Reputation: 35263

The object you are returning from login.UserVM has only authenticate property and doesn't have userdata or apiUrl properties. So, instead using an IIFE to create an object, set login.UserVM to a constructor function similar to login.UserData. And then use new operator to create the viewModel object. Now the viewModel will have userdata and apiUrl properties (remove the return from the function)

Also, you need to change the HTML bindings to: data-bind="value:userdata.UserName". This looks for the userdata property inside the bound viewModel

var login = {}; //login namespace

//Constructor
login.UserData = function () {
    var self = this;
    self.UserName = ko.observable("");
    self.Password = ko.observable("");
};
//View-Model
login.UserVM = function () {
    this.userdata = new login.UserData(),
    this.apiUrl = 'http://localhost:9090/',
    this.authenticate = function () {
        var data = JSON.parse(ko.toJSON(this.userdata));
        console.log(data)
        //var service = this.apiUrl + '/api/Cryptography/Encrypt';
        //DBconnection.fetchdata('POST', service, JSON.stringify(data.Password), response, function () { console.log('Cannot fetch data') }, null, true);
        function response(res) {
            console.log(res)
        }
    }
}; // remove the () from here

ko.applyBindings(new login.UserVM()); /* Apply the Knockout Bindings */
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<form id="loginform" name="loginForm" method="POST">
    <div id="form-root">
        <div>
            <label class="form-label">User Name:</label>
            <input type="text" id="txtFirstName" name="txtFirstName" data-bind="value:userdata.UserName" />
        </div>
        <div>
            <label class="form-label">Password:</label>
            <input type="text" id="txtLastName" name="txtLastName" data-bind="value:userdata.Password" />
        </div>
        <div>
            <input type="button" id="btnSubmit" value="Submit" data-bind="click: authenticate" />        
        </div>
    </div>
</form>

Upvotes: 1

Related Questions