FOR MZ !! Howto get data out of a promise ? SOLVED WITH using async twice and await twice

Nafraju

Regular
Regular
Joined
Mar 20, 2022
Messages
41
Reaction score
6
First Language
German
Primarily Uses
RMMV
Hi,

Code:
Window_SaveInfo.prototype.refresh = function() {
  this.contents.clear();
  this.resetFontSettings();
  var dy = 0;
  dy = this.drawGameTitle(dy);
  if (!this._valid) return this.drawInvalidText(dy);
  const saveName = DataManager.makeSavename(this.savefileId());
  this._saveContents = StorageManager.loadObject(saveName); //############
  console.log(this._saveContents);///
  this.drawContents(dy);
};
from this line with //############
I get via console.log(this._saveContents); this

Code:
Promise {<pending>}__proto__: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: Object
actors: Game_Actors {_data: Array(5), @: "Game_Actors"}
map: Game_Map {_interpreter: Game_Interpreter, _mapId: 3, _tilesetId: 12, _events: Array(15), _commonEvents: Array(8), …}
party: Game_Party {_inBattle: false, _gold: 1000000, _steps: 7, _lastItem: Game_Item, _menuActorId: 0, …}
player: Game_Player {_x: 12, _y: 3, _realX: 12, _realY: 3, _moveSpeed: 3, …}
screen: Game_Screen {_brightness: 255, _fadeOutDuration: 0, _fadeInDuration: 0, _tone: Array(4), _toneTarget: Array(4), …}
selfSwitches: Game_SelfSwitches {_data: {…}, @: "Game_SelfSwitches"}
switches: Game_Switches {_data: Array(27), @: "Game_Switches"}
system: Game_System {_saveEnabled: true, _menuEnabled: true, _encounterEnabled: true, _formationEnabled: true, _battleCount: 0, …}
timer: Game_Timer {_frames: 0, _working: false, @: "Game_Timer"}
variables: Game_Variables {_data: Array(1903), @: "Game_Variables"}
__proto__: Object

But if I want to access the data of this._saveContens in example ._saveCounts
I get undefined.

I can not use DataManager instead of StorageManager because it must be happened before any gamedata is loaded.

The problem in general is that I am transfering from MV to MZ
and I need to adapt my plugin(s).

I am guessing, the issue is, that there is no waiting until the promise is fulfilled ?
But I don't know how to solve this - I tried everything I could think of.


Nafraju

[If the post is not done in the right place please move it.]

The features of those MV-Plugins are not available in any MZ-Plugins to buy or for free,

so I need to adapt mine.
 
Last edited:

gstv87

Regular
Regular
Joined
Oct 20, 2015
Messages
3,367
Reaction score
2,570
First Language
Spanish
Primarily Uses
RMVXA
But if I want to access the data of this._saveContens in example ._saveCounts
I get undefined.
when.

saveContents is a placeholder for the file data to be displayed in the menu.
it only exists after loading said data from disk.
you have it right there, in the very instruction you're marking.
Code:
this._saveContents = StorageManager.loadObject(saveName)

"with module StorageManager, do loadObject, (here), place result in _saveContents"
 

Nafraju

Regular
Regular
Joined
Mar 20, 2022
Messages
41
Reaction score
6
First Language
German
Primarily Uses
RMMV

Directly after in this.drawContents(dy); the data are needed in all what happends in this called function.

this._saveContents = StorageManager.loadObject(saveName); //############ get data
console.log(this._saveContents);/// checking via console if data is loaded
this.drawContents(dy); use data

If I log in console only this._saveContents
I get a result with a warning (as info) Value below was evaluated just now.

If I do console.log(this._saveContents._saveCounts);/// I get undefined

I think it is because there is a delay with the promise until it is fulfilled
but the code isn't waiting ...

And I don't know how to solve this.
 

gstv87

Regular
Regular
Joined
Oct 20, 2015
Messages
3,367
Reaction score
2,570
First Language
Spanish
Primarily Uses
RMVXA
what data?
drawContents is a window method, and it's usually empty, overwritten by whatever window is being drawn.

where are you in this code, what data are you drawing, and why are you using a saveinfo window?
 

Nafraju

Regular
Regular
Joined
Mar 20, 2022
Messages
41
Reaction score
6
First Language
German
Primarily Uses
RMMV
what data?
drawContents is a window method, and it's usually empty, overwritten by whatever window is being drawn.

where are you in this code, what data are you drawing, and why are you using a saveinfo window?
the data which are show above out of this Promise like
_saveCounts .. Variables ..

screenshot.png

This content of this saveinfo window is the utmost important think for me as the developer,
because there I have all variables (I need to see at once) shown (not like F9)
and I have the possiblity to save it / and see what is saved ...

In MV it works nicely because the savefiles are handled easier.
Now I want to go with MZ ..
so I need to transfer this plugin
The last days I adapt the whole plugin .. all is working
only this point not.

I can not use DataManager instead of StorageManager because it must be happened before any gamedata is loaded.
 

Aerosys

Regular
Regular
Joined
Apr 23, 2019
Messages
1,045
Reaction score
1,107
First Language
German
Primarily Uses
RMMZ
You don't "get" data from a promise, but you add a callback with an action about what should happen when your promise is fulfilled.

Code:
StorageManager.loadObject("whatever").then(contents => /* do something */)

Which makes it challenging to "get" the contents out of this inner function. What you can do is preload information on game start and bind the contents to a global variable to retrieve it later.

Code:
var NAF = NAF || { };

(function() {
    const alias = Scene_Boot.prototype.start;
    Scene_Boot.prototype.start = function() {
        alias.call(this);
     
        StorageManager.loadObject("whatever").then(contents => NAF._contents = contents)
    }
})()

At this point, I recommend to learn what "aliasing" is in JS. In a nutshell, it injects custom code in the core code so the core code runs as before but it also calls your custom code.

NAF._contents now contains the requested file's contents. You can retrieve this content anywhere in your code, as NAF is in the global scope.

This is one way to handle it, but I don't think this would be the best. RPG Maker already provides functions to read save data before loading the save game. I already did that here: https://forums.rpgmakerweb.com/index.php?threads/rogue-like-plugins-mv-mz.157008/, where the Loading Screen shows additional Save Stat data.

DataManager.savefileInfo(id) returns some save stat data as an object, not as a promise. When your requested info is missing, we can easily add it:

Code:
var alias_DataManager_makeSavefileInfo = DataManager.makeSavefileInfo;
DataManager.makeSavefileInfo = function() {
    const info = alias_DataManager_makeSavefileInfo.call(this);
    info.saveCount = $gameSystem.saveCount();
    info.battleCount = $gameSystem.battleCount();
    /* ... */
    return info;
}

DataManager.savefileInfo(id) will now return saveCount & battleCount for simple retrieval.

Tip: You MUST save a game to make this information available! It will not work on already existing save stats.
 

Nafraju

Regular
Regular
Joined
Mar 20, 2022
Messages
41
Reaction score
6
First Language
German
Primarily Uses
RMMV
Which makes it challenging to "get" the contents out of this inner function. What you can do is preload information on game start and bind the contents to a global variable to retrieve it later.

That is not the problem. This working by return result;

The problem is the timing.

JavaScript:
Window_SaveInfo.prototype.refresh = function() {
  this.contents.clear();
  this.resetFontSettings();
  var dy = 0;
  dy = this.drawGameTitle(dy);
  if (!this._valid) return this.drawInvalidText(dy);
  const saveName = DataManager.makeSavename(this.savefileId());
  this._saveContents = StorageManager.loadObject(saveName).then(function(result){
    //do some operation on result
    console.log(result);///
    console.log(result.PromiseResult);///
    console.log(result.system.saveCount());///
    return result;
  });
  /* HERE needs the code to wait until the Promise is fulfilled */
  /* when it is fulfilled then ... do ... go on */
  console.log(this._saveContents.system.saveCount());
  this.drawContents(dy);
};
 

Aerosys

Regular
Regular
Joined
Apr 23, 2019
Messages
1,045
Reaction score
1,107
First Language
German
Primarily Uses
RMMZ
And this is not the flow a function in a Window class should have. A window shows information that is available right now and not any millisecond later. You cannot get the return value from a Promise without any ugly workarounds.

So, IF you decide to preload data as I showed you, your Window function will look like this:

Code:
Window_SaveInfo.prototype.refresh = function() {
  this.contents.clear();
  this.resetFontSettings();
  var dy = 0;
  dy = this.drawGameTitle(dy);
  if (!this._valid) return this.drawInvalidText(dy);

  this._saveContents = NAF._contents // <-- probably needs some tuning
  // but you eliminated the lookup via StorageManager

  console.log(this._saveContents);
  this.drawContents(dy);
};

I still recommend you go the other way with DataManager.savefileInfo(id). Your Plugin is pretty close to mine when it comes to displaying data, and for me, this way took me around 10 minutes overall to get it to work.
 

Nafraju

Regular
Regular
Joined
Mar 20, 2022
Messages
41
Reaction score
6
First Language
German
Primarily Uses
RMMV
SOLVED WITH using async twice and await twice :smile:

JavaScript:
Window_SaveInfo.prototype.refresh = async function() {
  this.contents.clear();
  this.resetFontSettings();
  var dy = 0;
  dy = this.drawGameTitle(dy);
  if (!this._valid) return this.drawInvalidText(dy);
  this._saveContents = null;
  if (this._valid) {
    const saveName = DataManager.makeSavename(this.savefileId());
    this._saveContents = await StorageManager.loadObject(saveName).then(async function(result){
      //do some operation on result
      console.log(result);///
      console.log(result.system.saveCount());///
      return await result;
    });
  };
  if (this._saveContents) {
    console.log('loaded', this._saveContents);
    console.log('loaded count', this._saveContents.system.saveCount());
    this.drawContents(dy);
  };
};
 

Aerosys

Regular
Regular
Joined
Apr 23, 2019
Messages
1,045
Reaction score
1,107
First Language
German
Primarily Uses
RMMZ
Nice!

For anyone else coming into this Thread, "await" is a keyword that works only in MZ!
 

Nafraju

Regular
Regular
Joined
Mar 20, 2022
Messages
41
Reaction score
6
First Language
German
Primarily Uses
RMMV
INFO MZ

All Save/Delete/... operations can also have a delay until the datas were updated
so ..
JavaScript:
/* !!! Must HAVE a delay until the Storage ist updated !!! */
setTimeout(() =>this._listWindow.refresh(), 20);
 

Latest Threads

Latest Posts

Latest Profile Posts

Looooooonnnnggg maaaaannnnn
Yknow what? Im seriously considering recruiting a manager to oversee my games development.
Because I cannot focus or complete these tasks by myself. I need someone to give me orders, without having them be my boss.
yp_4vS.png

Remember my latest plugin for rpg maker mz:

Acknowledgement Window is now available!

Take a look here:

Got my focus back, 9/59 maps have the door fix in place now.
Making a small RMMV project has made me realize that I've never actually made a credits sequence for a game.

Forum statistics

Threads
136,799
Messages
1,270,150
Members
180,551
Latest member
MidnightDarpy
Top