0

I have a simple Ionic Page containing a 'global' variable called 'mood', accessible like 'this.mood'.

Inside a function of my page I make use of an intro.js library callback. This is my code:

import introJs from 'intro.js/intro.js';
[...]
var mood;
[...]
this.introJsVar=introJs.introJs();
this.mood='init';
[...]
intro() {
    var tutorialSteps={ steps: [{
      element: 'somelementid',
      intro: 'Hello world',
      position: 'right'
    }] }

    this.introJsVar.setOptions(tutorialSteps);
    this.mood='foo';               // This works
    console.log(this.mood);        // logs 'foo'

    this.introJsVar.onchange(function(targetElement) { 
        this.mood='bar';               //This DOES NOT work
    });

    this.introJsVar.start();
  }
}

How may I modify the value of the variable 'mood' inside the callback?

It seems that inside the callback onchange the previous context gets lost: 'this' contains a lot of variable useful to the library intro.js but lose the variables declared and used in the previous context, that is the one of the page... An explanation of what is going on it would be also very appreciated.

EDIT (secondary problem and solution): Truly, I need to access both contexts: the one of the Ionic page (outer) which contains the variable 'mood' and the one of the callback onchange (inner) which contains info about the change happened (which triggered the callback), like the number of step of the intro.js tutorial the user has changed to, that I was able to find in 'this' before using arrow function. ( variable '_currentStep': https://introjs.com/docs/intro/api/#introjsonchangeprovidedcallback)

I can solve the main problem using an arrow function, but, at that point, the context (this) becomes the outer one, I think, for I can access the variable 'mood' with 'this.mood' but I cannot access the inner context variables like '_currentStep'. If I try to do 'this._currentStep' the compiler says the _currentStep variable does not exist in the context of the page (and it is true). To access both information, I found finally a solution: 1) using an arrow function instead of function() let access to the outer context 2) variables of the inner context are contained inside this.introJsVar (look at my code to know what it is) so it is possibile to get the current step like this.introJsVar._currentStep

Sasha Grievus
  • 2,566
  • 5
  • 31
  • 58

1 Answers1

2

It doesn't get lost, the this inside the anonymous function function(targetElement) {} belongs/reference the function itself.

If you can, use an arrow function and it will work, as an arrow function doesn't create a blocking scope, as a function(){} does.

this.introJsVar.onchange( (targetElement) => { 
    this.mood='bar';
});
Asons
  • 84,923
  • 12
  • 110
  • 165
  • what do you mean by "belongs to the function itself"? And what changes adding the arrow function? Just trying to really get what is going on, thank you :) – Sasha Grievus Jul 07 '18 at 18:37
  • 1
    @SashaGrievus Updated a little, does it make sense now? – Asons Jul 07 '18 at 18:41
  • Yea, clearer, thank you a lot! Last question: the context ('this') available this way is the external one, if I'm guessing right. Truly, I need also to read some information that was contained in the context ('this') belonging to the function itself. I can access both using the arrow function? – Sasha Grievus Jul 07 '18 at 22:37
  • @SashaGrievus Not sure I understand exactly what you mean, but simply try and come back with it, if you can't make it work, and we find a solution for you. – Asons Jul 07 '18 at 22:39
  • Sorry, i'm explaining the problem in a very bad way, I know, but there's something I am missing and this makes difficult to explain myself. I tried to explain my problem deeper in an edit of the question. As soon as I understand, I'll correct the question for people passing by be able to understand. Thank you a lot – Sasha Grievus Jul 08 '18 at 18:34
  • 1
    @SashaGrievus Where do `'this._currentStep' ` come from? .. can you set up a fiddle, based on the code above, and show where it is positioned. – Asons Jul 08 '18 at 18:38
  • Here, that's the problem: I don't know. Before, if I did: this.introJsVar.onchange(function(targetElement) { console.log(this. _currentStep) }); the _currentStep was printed. Trying to set up a fiddle ^^' – Sasha Grievus Jul 08 '18 at 18:48
  • Sorry, seems to be too complicate to be able to set up a fiddle. Anyway, making more tests I found a solution: this.introJsVar contains the variables I need. So this.introJsVar._currentStep returns what I was searching for. Still disappointed in not understanding what is going on but at least I have a solution. Sigh! – Sasha Grievus Jul 08 '18 at 19:10
  • 1
    @SashaGrievus Okay, great. Just give it some time, I have to that all the time with all new stuff that comes along (this one included), and then, when one take a second look at a later time, if very often fall into place :) – Asons Jul 08 '18 at 19:14
  • You're totally right! Thank you so much for helping out! – Sasha Grievus Jul 09 '18 at 07:45