console.log behaves differently when called from script?

Grundulum

Warper
Member
Joined
Jul 1, 2020
Messages
4
Reaction score
0
First Language
English
Primarily Uses
RMMV
I am attempting to debug a script using the console, and it isn't being very helpful. When I playtest my game and call console.log from my script (by typing QuizManager.setupQuestion()), I get an "Uncaught TypeError".

JavaScript:
//=============================================================================
// QuizManager.js
//=============================================================================
/*:
 * @plugindesc Manages a quiz
 *
 * @author Me
 *
 * @help
 *
 * Anything users might need to know about using your plugin.
 *
 * TERMS OF USE
 * What people who use your plugin are allowed to do with it.
 *
 * COMPATIBILITY
 * Any compatibility issues you know of ...
 */
 
var QuizManager = QuizManager || {};

(function() {
    
    var $Flashcards = null;
    var $FlashcardFaces = null;
    
    DataManager._databaseFiles.push({name: '$Flashcards', src: 'Flashcards.json'});
    DataManager._databaseFiles.push({name: '$FlashcardFaces', src: 'FlashcardFaces.json'});
    
    QuizManager.questionSetup = function() {
        // Randomly generate the question number
        var questionNum = 1 + Math.floor(10 * Math.random());
        
        // Entry 0: the prompt
        console.log(questionNum);
        console.log($Flashcards[questionNum]);
        
    };
  
})();
Line number 36 is the problem, according to the traceback. The Uncaught TypeError points to that line and tells me "Cannot read property 'X' of null" -- X is a random number, generated correctly in line 32. If I type $Flashcards[X] (or even console.log($Flashcards[X])) in to the console, though, I get what I expect: a list of keywords and values associated with that flashcard.

-------------------------

I have a related question that may be better suited for separate thread. Is it possible for RMMV code that works perfectly one day to stop working at a later point in time? This exact code functioned last week, but now I'm trying to debug the console so that I can debug the script.
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
1,869
Reaction score
1,218
First Language
English
Primarily Uses
RMMV
It looks like your second console.log is trying to output an element of $Flashcards before it's actually been populated.
 

Grundulum

Warper
Member
Joined
Jul 1, 2020
Messages
4
Reaction score
0
First Language
English
Primarily Uses
RMMV
Does this mean I need to add the DataManager lines to something that runs at initialization? Again, this plugin worked just fine last week, so I'm completely in the dark about what could be breaking.

Edit: I should add that I don't "speak" Javascript (yet), so if the answer to the above question is "yes" I would appreciate a link to a pre-existing function I could Frankenstein into my code.

Edit again: this "awaiting moderator approval" thing is a bit of a bummer.
 
Last edited:

Hudell

Dog Lord
Veteran
Joined
Oct 2, 2014
Messages
3,365
Reaction score
3,133
First Language
Java's Crypt
Primarily Uses
RMMV
try moving those two lines to the top, outside of the function:

Code:
    var $Flashcards = null;
    var $FlashcardFaces = null;
 

Grundulum

Warper
Member
Joined
Jul 1, 2020
Messages
4
Reaction score
0
First Language
English
Primarily Uses
RMMV
Hudell's suggestion worked. Thanks! What terms do I need to Google to understand *why* that worked?
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
1,869
Reaction score
1,218
First Language
English
Primarily Uses
RMMV
Hudell's suggestion worked. Thanks! What terms do I need to Google to understand *why* that worked?
The basic answer is that when you do this null setting outside of the function, it's executed as part of initialising the main game window, which happens before everything else.

Inside the function you had it in originally, you were trying to access elements of an array you'd *just* made null, before any other code had the chance to put something into it.
 

Hudell

Dog Lord
Veteran
Joined
Oct 2, 2014
Messages
3,365
Reaction score
3,133
First Language
Java's Crypt
Primarily Uses
RMMV
Not exactly. By adding those lines inside the function, you created two local variables. Any code inside this function would use those variables, but the DataManager is not inside it, so it was creating two new variables with the same name and storing the content there. When you tried to access those variables from the console window, you would access the same variables as the DataManager instead of the two local variables you created there.

By moving those two lines outside, everything would use the same variables.
 

Grundulum

Warper
Member
Joined
Jul 1, 2020
Messages
4
Reaction score
0
First Language
English
Primarily Uses
RMMV
Thanks for the explanations. I feel like I understand now why the script was breaking, though from what you describe it should not really have worked in the first place (and yet it did!).

Edit: this leads to a further question about using global vs local variables. I'm admittedly new to RMMV and Javascript (I speak Fortran fluently, though -- please stop laughing), but my impression was that global variables should be avoided where possible since they could lead to name conflicts or other issues. Did I read correctly? Is this a case where the global variable *is* necessary?
 

Solar_Flare

Veteran
Veteran
Joined
Jun 6, 2020
Messages
319
Reaction score
128
First Language
English
Primarily Uses
RMMV
It's not really a question of whether global variables are necessary or not. The DataManager specifically loads JSON files into global variables - that's just what it does. (In RPG Maker, built-in global variables usually begin with the $ character, but that's just a convention they chose.) If you want to make those variables non-global, you will need to load the files manually instead of letting the DataManager do it for you.

When determining whether the variable needs to be global, I think a good guideline is... would someone want to make a plugin to extend yours? If so, would they need that variable? For example, I would recommend making any class declarations (like Window_MyCustomWindow) global so that others can extend or alter your custom classes. (In JavaScript, functions and classes are technically variables too.) On the other hand, data only needed by your plugin could be kept local to your anonymous function scope.
 

heartcase

时人不识余心乐,将谓偷闲学少年。
Member
Joined
Jun 12, 2020
Messages
5
Reaction score
1
First Language
Chinese
Primarily Uses
RMMV
just remove these two lines:
JavaScript:
    var $Flashcards = null;
    var $FlashcardFaces = null;
and to be more accurate (if you are referring the global variable ), change the output line into:
Code:
console.log(window.$Flashcards[questionNum]);
Google`JavaScript Scope Chain` if you want to know more about this.
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Profile Posts

Excited to be nearing the end of setting up my own custom Point-And-Click system template! Just need to iron out some kinks, get an input text system going, add animations to buttons, and then finalize my button-mashing event system and it'll be complete >:3c
AlcTheHero wrote on Mystic_Enigma's profile.
hi.
Still recovering from my laptop's transformation into a brick. I hope to be back to making soon.
Urgh. That sense of frustration when I tell my husband the plot of my game, bullet points, and at the end he looks and me and says 'that's it? Final Fantasy has more twists and turns.' Me: Ahrug! Bullet points!
Another day, another microwave accidently set on fire! >.< I just wanted popcorn for a movie night...

Forum statistics

Threads
99,638
Messages
967,588
Members
131,308
Latest member
tuyetky01
Top