loki
loki

Reputation: 648

How to access the methods of the controller from another function?

So I am making a call to my xsjs using the promise interface of jQuery as follows in my onBeforeRendering method of my Controller named Questionnaire.controller.js which is binded to view Questionnaire.view.xml

onBeforeRendering: function() {jQuery.get("/prototype/OnlineQuestionnaire/getQuestionsAndResponseChoices.xsjs", {
            questionnaireResponseId: jQuery.sap.storage.get("QuestionnaireResponseId"),
            password: jQuery.sap.storage.get("Password")
        }).done(function(data){
     that.OnlineQuestionnaire.controller.Questionnaire.prototype.checkData(); 
}).fail(function(jqXHR){
            MessageBox.show(jqXHR.responseText, "ERROR", "Service Call Error");
        });
    },
    checkData: function(){console.log("Hi");
    }

In my .done() I wanted to access the checkData() method but I was not able to because I donot know how to call the controller's method. I tried various ways :

sap.ui.controller("OnlineQuestionnaire.controller.Questionnaire").checkData();

then I tired :

sap.ui.getCore().byId('Questionnaire').getController().checkData();

This returned me undefined. So I am still unable to figure out how do I get my controller and then call its method. But I found a workaround and made it work using following, first i defined var that = this; so now my that consists of window object and then I called following':

that.OnlineQuestionnaire.controller.Questionnaire.prototype.checkData();

But there should be simplier way and I am missing something out. Can anyone suggest a simplier solution.

Upvotes: 0

Views: 5050

Answers (2)

Andrew Naumovich
Andrew Naumovich

Reputation: 1450

Well, if I understood you correctly, your problem is the lost context of the controller withing the done callback.

There are two ways to solve this:

  1. do the

var that = this;

at the beginning of your onBeforeRendering function and inside the done callback just call:

that.checkData();

  1. you can set the right context via native js function bind. It will look like the following:

onBeforeRendering: function() { jQuery .get("/prototype/OnlineQuestionnaire/getQuestionsAndResponseChoices.xsjs", { questionnaireResponseId: jQuery.sap.storage.get("QuestionnaireResponseId"), password: jQuery.sap.storage.get("Password") }) .done(function(data) { this.checkData(); }.bind(this)) .fail(function(jqXHR) { MessageBox.show(jqXHR.responseText, "ERROR", "Service Call Error"); }); }, checkData: function() { console.log("Hi"); }

To undertand this stuff more, you can read any info about JS context, scope and closure terms, i.e. http://ryanmorr.com/understanding-scope-and-context-in-javascript/

Upvotes: 2

matbtt
matbtt

Reputation: 4231

You can use bind to ensure that this points to your controller inside the done method. Please read about the special behaviour of this in JavaScript compared to other programming language.

jQuery.get("/prototype/OnlineQuestionnaire/getQuestionsAndResponseChoices.xsjs", {
    questionnaireResponseId: jQuery.sap.storage.get("QuestionnaireResponseId"),
    password: jQuery.sap.storage.get("Password")
}).done(function(data) {
    this.checkData(); 
}.bind(this)).fail(function(jqXHR) {
    MessageBox.show(jqXHR.responseText, "ERROR", "Service Call Error");
});

There are other solution, e.g. using a helper variablte that to preserve the original context but I don't like that, as it makes your code less readable.

I assume that checkData should do something with your data. Therefore you should pass them to the method:

this.checkData(data)

Upvotes: 2

Related Questions