KnockoutJS Calling ViewModel function from inside another function - javascript

I'm having the following ViewModel in which I have few functions. And I am trying to call another function located in the same ViewModel.
This is my ViewModel:
var UploadFileListVewModel = function() {
var self = this;
Inside I have an init function:
//initialize view model
this.init = function () {
$.ajax({
url: '/Files/LastUploadedFiles',
type: 'POST',
cache: false,
data: {},
}).done(function (result) {
//doing stuff
});
}
Sometime later on I perform an remove file operation and once it completed I want to run my init fuction again
self.removeFile = function(item)
{
$('#fileModal').modal('hide'); //closing modal dialog
$.ajax({
//url: '#Url.Action("RemoveFile", "Files")',
url: '/Files/RemoveFile',
type: 'POST',
data: { 'file_id': self.fileToRemoveId() },
cache: false
}).done(function (result) {
//doing stuff
this.init();
});
}
I'm getting an error this.init() is not a function.
I would really appreciate if somebody could point me into right direction on how to call this init() function or suggest any workaround.

The this keyword inside the callback function is not your ViewModel. That's why you created the self, so you can use it inside events, arrays, callback functions etc.
So, you should change your code to self.init().

Related

How to handle this with async Ajax request and callback

So this function getXmlData() get's called across the app who's main responsibility is to return xml to and save it to a variable, in this example below it is 'test'
var test = getXmlData();
function getXmlData() {
queryData(getData);
}
function getData(xml) {
if (xml) {
return xml;
}
}
function queryData(callback){
$.ajax({
url: "/echo/JSON",
type: 'POST',
success: function(xml){
callback(xml);
},
error: function(){
console.log("Error!!");
}
})
}
Now we know that here parent function will return before the callback is executed and so 'test' variable will be undefined.
I'm not sure how can I handle this situation here. I'm tied to using this structure. I basically want getXmlData to return xml that is being returned in queryData. Suggestions!?

Passing GET data from one function to another

I'm trying to pass some data from one function to another. I have made a successful AJAX call and got the data. But what I can't figure out now is how to pass that data to another function.
'use strict'
$(document).ready(function() {
console.log('Page Ready');
changeColor();
getData();
});
function getData(data) {
var root = 'http://jsonplaceholder.typicode.com',
data;
data = $.ajax ({
url: root + '/posts/1',
type: 'GET',
success: function(data) {
console.log(data.body);
}
});
}
function changeColor(data) {
$('button').on('click', function() {
$('.classy').toggleClass('blue');
$('.classy').append(data.body);
});
}
Is someone able to advise how I can get the data from getData and pass it to changeColour?
Just call the changeColor method in the ajax success and pass the data. Removed the data variable from getData as there was no need for it.
'use strict'
$(document).ready(function() {
console.log('Page Ready');
changeColor();
getData();
});
function getData() {
var root = 'http://jsonplaceholder.typicode.com';
$.ajax ({
url: root + '/posts/1',
type: 'GET',
success: function(data) {
console.log(data.body);
changeColor(data); //Just call the method here
}
});
}
function changeColor(data) {
$('button').on('click', function() {
$('.classy').toggleClass('blue');
$('.classy').append(data.body);
});
}
Merely invoke your changeColor() function from success: function.
function getData(data) {
var root = 'http://jsonplaceholder.typicode.com',
data = $.ajax ({
url: root + '/posts/1',
type: 'GET',
success: function(data) {
console.log(data.body);
changeColor(data);
}
});
}
Note that I dropped your simple data; line, which has no sense.
You could put the changeColor function into the success call of the getData function.
function getData(data) {
var root = 'http://jsonplaceholder.typicode.com',
data;
data = $.ajax ({
url: root + '/posts/1',
type: 'GET',
success: function(data) {
console.log(data.body);
changeColor(data);
}
});
}
You basically have two options: call the changeColor function from within the success function, or in your success function store the data in a variable that can be accessed elsewhere (either directly by changeColor or passed into changeColor).
The second option can be achieved by either accessing a global variable (not really a good idea), or passing in an object that will then be passed into changeColor. Which one is best really depends upon your usage.

How to use requirejs to work with ajax callbacks?

If I have to leverage niceties of jQuery AJAX API and set my own custom settings for each ajax call my app makes like below:
Say I have a page which displays employee information within table by making ajax calls to some API.
define(["jQuery"], function($) {
var infoTable = function (options) {
function init() {
// Provide success callback
options.success_callback = "renderData";
getData();
}
function renderData() {
// This callback function won't be called as it is not
// in global scope and instead $.ajax will try to look
// for function named 'renderData' in global scope.
// How do I pass callbacks defined within requirejs define blocks?
}
function getData() {
$.ajax({
url: options.apiURL,
dataType: options.format,
data: {
format: options.format,
APIKey: options.APIKey,
source: options.source,
sourceData: options.sourceData,
count: options.count,
authMode: options.authMode
},
method: options.method,
jsonpCallback: options.jsonpCallback,
success: options.success_callback,
error: options.error_callback,
timeout: options.timeout
});
}
}
return {
init: init
}
}
How do I achieve this?
I know we can use JSONP request as require calls but that restricts me to using jsonp, making GET requests and all other features $.ajax offers.
This example would let you either use a default success callback, or provide an override, using:
success: options.successCallback || renderData
(The example uses jsfiddle rest URLs - this fact is unimportant, and stripped out the data object to keep the example short)
define("mymodule", ["jquery"], function($) {
function renderData() {
console.log("inside callback");
}
function getData(options) {
$.ajax({
url: options.apiURL,
dataType: options.format,
method: options.method,
jsonpCallback: options.jsonpCallback,
success: options.successCallback || renderData,
error: null,
timeout: options.timeout
});
}
return {
getData: getData
}
});
require(["mymodule"], function(m) {
console.log(m, m.getData({
apiURL: "/echo/json/"
}));
console.log(m, m.getData({
successCallback: function() { console.log("outside callback"); },
apiURL: "/echo/json/"
}));
});
Would print:
GET http://fiddle.jshell.net/echo/json/ 200 OK 263ms
Object { getData=getData()} undefined
GET http://fiddle.jshell.net/echo/json/ 200 OK 160ms
Object { getData=getData()} undefined
inside callback
outside callback

Access class variable in jquery

I have a select in my html and would like to add the options via ajax when the page loads. The options values are in my DB and I get them via a call to ajax. To do so, I'm writing a class in javascript but I just can't get my data when it runs. Please take a look :
--- Main.js ---
function MyLoader() {
this._clients = null;
this._code = null;
}
Loader.prototype = {
var context = this;
loadClients: function() {
$.ajax({
url: "my/php/",
type: "POST",
data: {...},
success: function(response) {
context._clients = response;
}
});
},
getCode: function() {...}
};
Then I have the following :
$(document).ready(function() {
var loader = new Loader();
loader.loadClients();
alert(loader._clients);
//Here I want to add my options to the select
});
My alert always returns null, and I don't understand why. I need to save my data in the class in order to access them anytime I need to.
Can you point me to the right direction to make all my stuff work ? Thank you for your answers.
Loader.prototype = { // v---callback parameter
loadClients: function(callback) {
$.ajax({
url: "my/php/",
context: this, // <---set success context
type: "POST",
data: {...},
success: callback // <---pass callback
});
},
getCode: function() {...}
};
$(document).ready(function() {
var loader = new Loader();
// v---pass callback
loader.loadClients(function(response) {
this._clients = response;
alert(this._clients);
//Here I want to add my options to the select
});
});
I believe that you need to do all of your dynamic loading inside of your 'success' callback, since it is loading asynchronously.
You need to do it inside the success callback since it's async:
Loader.prototype = {
var context = this;
loadClients: function() {
$.ajax({
url: "my/php/",
type: "POST",
data: {...},
success: function(response) {
context._clients = response;
alert(loader._clients);
//Here I want to add my options to the select
}
});
},
getCode: function() {...}
};
$(document).ready(function() {
var loader = new Loader();
loader.loadClients();
});

jQuery's AJAX call to a javascript class method

I'm a newbee about jQuery's workflow and I would like to setup a javascript class that uses an internal method to make an AJAX request. When the request returns with success, the jQuery AJAX callback should invoke a method owned by the class itself. That's the code:
function IXClock()
{
this.m_intervalID = 0;
this.startClock = function ()
{
this.m_intervalID = setInterval(this.tictac, 500);
}
this.stopClock = function ()
{
clearInterval(this.m_intervalID);
}
this.setClockTime = function(p_strTime)
{
$('#clock').html(p_strTime);
}
this.tictac = function ()
{
$.ajax
({
type: 'POST',
url: '/rap/rapClock.php',
complete: function (data)
{
this.setClockTime(data);
}
});
}
}
The class represents a clock, with an internal method (tictac) that requests "what's the time" on the server side.
After the server says the time, the jQuery's AJAX method should invoke the setClockTime method of the IXClock class. The invoke method will update the #clock div item in the html page.
The problem is that the method this.setClockTime() results unknown and the javascript return the "this.setClockTime is not a function" error.
The question is: is there a way to invoka a class method from the jQuery's AJAX callback ?
I think that the problem is that the this in your callback function is different from the this referring to IXClock. Try:
var thisClass = this ;
this.tictac = function ()
{
$.ajax
({
type: 'POST',
url: '/rap/rapClock.php',
complete: function (data)
{
thisClass.setClockTime(data);
}
});
}
Test Case (added to site which already has jQuery loaded):
function uClass () {
this.testFunction = function(input) {
alert(input) ;
}
this.ajaxFunction = function() {
var myClass = this ;
$.ajax({
type: 'POST',
url: '/',
complete: function(data) {
alert(myClass.testFunction) ;
myClass.testFunction(data) ;
this.testFunction(data) ;
}
}) ;
}
}
var k = new uClass() ;
k.ajaxFunction() ;
It happens bacause your callback function leave in global context.
You can choose 2 ways
Use .bind function to bind context to callback function http://www.robertsosinski.com/2009/04/28/binding-scope-in-javascript/
jQuery's AJAX supports transfer some data to callback function. You can write smth like this:
:
this.tictac = function () { $.ajax ({ type: 'POST', context:this, url: '/rap/rapClock.php', complete: function (data) { this.setClockTime(data); } }); }
}
this does not refer to IXClock in your ajax callback. this allways points to the current scope (have a look at this document). You need to do something like this:
this.prototype.tictac = function ()
{
var self = this;
$.ajax
({
type: 'POST',
url: '/rap/rapClock.php',
complete: function (data)
{
self.setClockTime(data);
}
});
}
You can also use jQuery's .proxy()-function for this purpose:
this.prototype.tictac = function ()
{
$.ajax
({
type: 'POST',
url: '/rap/rapClock.php',
complete: $.proxy(function (data) {
this.setClockTime(data);
}, this)
});
}
The this in the result handler is not what you expect it is. (It is not the IXClock instance)
function IXClock()
{
this.m_intervalID = 0;
}
IXClock.prototype = {
startClock: function ()
{
this.m_intervalID = setInterval(this.tictac, 500);
},
stopClock: function ()
{
clearInterval(this.m_intervalID);
},
setClockTime: function(p_strTime)
{
$('#clock').html(p_strTime);
},
tictac: function ()
{
var that = this;
$.ajax({
type: 'POST',
url: '/rap/rapClock.php',
success: function (data) { // You want success here, not complete, IMO
that.setClockTime(data);
}
});
}
}
If you ask me, that ajax call is doing evil. It does not seem to send any data, nor modify any
state on the server, but is expecting/getting/using data from the php, yet is using the POST method.
Should've been
$.get('/rap/rapClock.php', function (data) {
that.setClockTime(data);
});
One simple solution is, to keep your callback function as self = this. This will support inheritance also.
class Record{
get_data(){
self = this;
$.ajax({
type : "GET",
url : "/get_url",
dataType : "json",
contentType: "application/json; charset=utf-8",
data : {},
success : function(data){
console.log(data);
self.load_table(data);
},
});
}
static load_table(data){
console.log(data);
}

Categories