Bruse
Bruse

Reputation: 313

Knockout access to variable

I have variable with some properties, and function I'm trying to get to the properties, but this give me empty vars. What can I do? for example:

    var exports = {

    city: ko.observable(),
    street: ko.observable().extend({ required: true, number:true}),

    back : function(){
       console.log(this.city);
    },

HTML

        <button data-bind="click: back" class="btn btn-default">Back</button>

I'm also attached the full HTML and JS. on this, i cannot get this.myAcmout(). on respond function:

HTML

<div class="responses">
<div role="form" class="form-horizontal">

    <div class="form-group">
        <label class="col-sm-1 control-label">{{_t('Responses')}}</label>

        <div class="col-sm-10">

            <div class="form-control-static" data-bind="visible: request.responses().length == 0">
                {{_t('No responses.')}}
            </div>

            <table class="table table-striped table-hover col-sm-12"
                   data-bind="visible: request.responses().length > 0">
                <thead>
                <tr>
                    <th>{{_t('Created')}}</th>
                    <th>{{_t('Amount')}}</th>
                    <th>{{_t('Rate')}}</th>
                    <th>{{_t('Distance')}}</th>
                    <th></th>
                </tr>
                </thead>
                <tbody data-bind="foreach: request.responses()">
                <tr class="clickable">
                    <td>{{since()}}</td>
                    <td>{{amount}}</td>
                    <td>{{rate}}</td>
                    <td>{{distance}}</td>
                    <td>
                        <a data-bind="click: action">{{_t('Details')}}</a>
                </tr>
                </tbody>
            </table>

        </div>
    </div>


    <!-- ko if: !isRequestor -->
    <h5>{{_t('Your response')}}</h5>

    <div class="form-group" data-bind="css: { hideErrors: !hasBeenSubmittedOnce()}">

        <label class="col-sm-1 control-label">{{_t('Amount')}}</label>

        <div class="col-sm-2">
        <input type="text" id="myAmountInput" class="form-control" data-bind="'autoNumeric: myAmount'">
            </div>

        <div class="col-sm-1">
            <p class="form-control-static">{{ request.requestedCurrency }}</p>
        </div>

    </div>
    <!-- /ko -->


</div>


<div class="x-btn-row">
    <button class="btn btn-primary" type="button" data-bind="visible: !isRequestor, click: respond">
        {{isResponder() ? _t('Update response') : _t('Respond')}}
    </button>
    <button data-bind="visible: isRequestor || isResponder(), click: cancel" class="btn btn-danger">{{_t('Cancel')
        }}</button>
    <button data-bind="click: back" class="btn btn-default">{{_t('Back')}}</button>

</div>

JS

define(['knockout', 'knockout-validation', 'services/changeup', 'moment', 'lodash', 'plugins/router'], function (ko, validation, changeup, moment, _, router) {

ko.validation.configure({
    insertMessages: true,
    decorateElement: true,
    errorElementClass: 'error',
    errorMessageClass: 'help-inline '
});

function tick(){
    var request = exports.request;
    console.log('tick', request);
    if(request){
        request.endsIn(moment.utc(request.expiresAt).fromNow());
        _.each(request.responses(), function(rs){
            rs.since(moment.utc(rs.createdAt).fromNow());
        });
    }
}

function belongsToUserInfo(r){
    return r && exports.userInfo && r.username === exports.userInfo.username;
}

var timerId = setInterval(tick, 1000 * 10);

var exports = {

    isRequestor: undefined,

    myAmount: ko.observable().extend({ required: true, number:true}),

    isResponder: ko.observable(),

    request: undefined,

    userInfo: undefined,

    hasBeenSubmittedOnce : ko.observable(false),

    errors : ko.validation.group(this),

    action : function(){

    },

    back : function(){
    },

    cancel : function(){
    },

    respond: function(scope){
        console.log(this.myAmount());
        this.hasBeenSubmittedOnce(true);
        var r=confirm("Are you sure you want to give proposal? your current proposal is: " + exports.request.amount);
        if (r===true){
            if (!this.myAmount.isValid()){
                this.errors.showAllMessages();
            } else {
                changeup.respond(exports.request._id, exports.myAmount()).then(function(){
                    router.navigate('dashboard');
                });
            }
        }
    },

    activate: function (activationData) {
    }

};


return exports;

});

Upvotes: 1

Views: 1692

Answers (2)

Mark B
Mark B

Reputation: 1186

Other than the missing parenthesis (as other pointed out) I don't see a problem here. Can you post a fiddle with your complete code?

This one is working:

<input type="text" data-bind="value: city" />
<button data-bind="click: back" class="btn btn-default">Back</button>  


var exports = {
    city: ko.observable('Los Angeles'),
    street: ko.observable().extend({
        required: true,
        number: true
    }),

    back: function (data) {
        console.log(data.city());      
        // or
        console.log(this.city());
        console.log(this.city);//incorrect
    }
};
ko.applyBindings(exports);

http://jsfiddle.net/barryman9000/cdjbX/1/

Upvotes: 0

Paritosh Piplewar
Paritosh Piplewar

Reputation: 8122

I am not sure where you are seeing the null value but i guess it can due to this.city. To access observable value, you should do something like this

  back : function(){
 console.log(this.city()); 
},

notice () at the end of city. One more thing, the other most common thing why people see irrelevant value is because they defined this in wrong scope.

You should call this back funciton in this way

<button data-bind="click: exports.back()" class="btn btn-default">Back</button>     

Upvotes: 2

Related Questions