Keren Keren - 2 months ago 6
Javascript Question

When can use .then to use currently returned value?

I make a call to a function that makes an ajax call like this:

send.startMonitoring({'fetchMethod': 'notificationInterval', 'lastmodif':0}).then(function(value){
console.debug(value);
});


But the error I'm getting is this:


Uncaught TypeError: Cannot read property 'then' of undefined in
jquery


As in above, I'm calling startMonitoring function which is on another page and passing an object for it to make ajax call to the server. That function returns value from server and I want to be able to do something with it. That's why I'm trying to use .then to process the value returned.


Since I'm getting the above error, how could I modify it so that
returned value can be processed? Also how and when I can use .then()?


var interface = (function(config) {

return {

transporter: function(options) {
return config.ajax(options);
},

startMonitoring: function(options) {

var PERIOD_NOT_VISIBLE = 60000;
var PERIOD_VISIBLE = 5000;
var timer = 0;
var timestring = 0;

(function callThis(timestamp) {

interface.transporter(options).then(function(value) {

if (value[1].notification[0].output == null) {
timestring = value[1].notification[0].lastmodif;
console.log(timestring);
return value;
}


}).catch(function(e) {

});

timer = setTimeout(function(){

callThis();
if (interface.isMonitoring() == 0 ) {
clearTimeout(timer);
}
}, (document.hidden) ? PERIOD_NOT_VISIBLE : PERIOD_VISIBLE);

})();
}
};

})(settings);


This is how ajax calls made:

ajax: function(opt) {

var defaultData = settings.getDefaultDataset();
var self = this;
var opt = $.extend({}, defaultData, opt);
var output = [];
return new Promise(function(resolve, reject) {
token = window.es.token;
opt[token] = "1";
jQuery.ajax({

method: "POST",
url: self.system.path+"/index.php",
"data": opt,
error: function() {
reject('error');
},
success: function(result) {
output.push(opt, result);
resolve(output);
}
});

});
}

Answer

Change startMonitoring to accept and call a callback parameter

startMonitoring: function(options, callback) {
    var PERIOD_NOT_VISIBLE = 60000;
    var PERIOD_VISIBLE = 5000;
    var timer = 0;
    var timestring = 0;
    (function callThis(timestamp) {
        interface.transporter(options).then(function(value) {
            callback(value);
        }).catch(function(e) {
        });
        timer = setTimeout(callThis, (document.hidden) ? PERIOD_NOT_VISIBLE : PERIOD_VISIBLE);
    })();
},

Tidy up ajax to remove the Promise constructor anti-pattern, and to use .then of the promise returned by jQuery.ajax

ajax: function(opt) {
    var defaultData = settings.getDefaultDataset();
    var opt = $.extend({}, defaultData, opt);
    var output = [];
    var token = window.es.token;
    opt[token] = "1";
    return jQuery.ajax({
        method: "POST",
        url: this.system.path + "/index.php",
        "data": opt,
    })
    .then(function(result) {
        output.push(opt, result);
        return output;
    });
}

Change how you call startMonitoring to pass in a callback function

send.startMonitoring({'fetchMethod': 'notificationInterval', 'lastmodif':0}, function callback(value){
    console.debug(value);
});