Status
Not open for further replies.

p0_boy

anti-kumbaya
Veteran
Joined
Mar 26, 2019
Messages
64
Reaction score
29
First Language
English
Primarily Uses
RMMV
Hello, party people in the place to be-

I have the following Frankenstein function:

Code:
$._urlExists = function(url_to_check) {
        var result = false;
        // check if string  is valid url format, source: https://stackoverflow.com/a/5717133
        var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
        '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name
        '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
        '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
        '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
        '(\\#[-a-z\\d_]*)?$','i'); // fragment locator
        switch (!!pattern.test(url_to_check)) {
            case true:
                // check if url exists, source: https://stackoverflow.com/a/24297372
                var reader = new XMLHttpRequest();
                reader.open('get', url_to_check, true);
                reader.onreadystatechange = (function() {
                    if (reader.readyState === 4) {
                        //check to see whether request for the file failed or succeeded
                        if ((reader.status == 200) || (reader.status == 0)) {
                            result = true;
                        };
                    };
                });
                reader.send(null);
            break;
        };
        return result;
    };

Unfortunately, it seems to return false even if I use a valid and existing URL.

I have a feeling this has to do with the function not waiting for the XMLHttpRequest to complete. Save inserting a manual wait command, is there a better way to wait for the request to complete before returning a result?

Otherwise, what am I doing wrong?

As ever, thank you in advance!
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
3,713
Reaction score
2,830
First Language
English
Primarily Uses
RMMZ
Your code actually works; if you add a console.log to the if statement that sets result to true and display the value, it'll show "true", showing that both the URL was opened successfully and that the status code returned 200 or 0. However, your return result in the main function body is firing before the onreadystatechange event does, so it's showing false because it hasn't been set to true yet.

There is a way to return the result synchronously, but I haven't yet figured out how to make it work with your code.
 

Poryg

Dark Lord of the Castle of Javascreeps
Veteran
Joined
Mar 23, 2017
Messages
4,136
Reaction score
10,680
First Language
Czech
Primarily Uses
RMMV
I have a feeling this has to do with the function not waiting for the XMLHttpRequest to complete
Absolutely spot on. Using events like onReadyStatChange means asynchronous programming, during which you cannot use the return function. The solution is simple.
Code:
if (reader.status == 200 || reader.status == 0) $gameSystem._realSite = true;
 

p0_boy

anti-kumbaya
Veteran
Joined
Mar 26, 2019
Messages
64
Reaction score
29
First Language
English
Primarily Uses
RMMV
Thank you @Trihan and @Poryg for the confirmation / explanation / and fix.

I tried @Poryg 's suggestion, but I am still coming up with a false value:

Here's the function, modified based on @Poryg 's fix:
Code:
$._urlExists = function(url_to_check) {
        $gameSystem._urlExists = false;
        // check if string  is valid url format, source: https://stackoverflow.com/a/5717133
        var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
        '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name
        '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
        '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
        '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
        '(\\#[-a-z\\d_]*)?$','i'); // fragment locator
        switch (!!pattern.test(url_to_check)) {
            case true:
                // check if url exists, source: https://stackoverflow.com/a/24297372
                var reader = new XMLHttpRequest();
                reader.open('get', url_to_check, true);
                reader.onreadystatechange = (function() {
                    if (reader.readyState === 4) {
                        //check to see whether request for the file failed or succeeded
                        if ((reader.status == 200) || (reader.status == 0)) {
                            $gameSystem._urlExists = true;
                        };
                    };
                });
                reader.send(null);
            break;
        };
    };

I am calling it during Game Boot:
Code:
var _Scene_Boot_start = Scene_Boot.prototype.start;
    Scene_Boot.prototype.start = function() {
        _Scene_Boot_start.call(this);
        // get ip lookup services list
        var ip_lookup_url = $._ipLookupServicesURL();
        $._urlExists(ip_lookup_url);
        console.log($gameSystem._urlExists);
        if ($gameSystem._urlExists) $._getIPLookupServices(ip_lookup_url);
        console.log($gameSystem._IPLookupJSON);
    };

But it is still returning false.

Based on the terminology you introduced me to, a Google search revealed another Stackoverflow solution that uses async/await...
Code:
function getData() {
  return axios.get('https://jsonplaceholder.typicode.com/posts');
}

(async () => {
   console.log(await getData())
})()

But I am confused as to how I would implement it in my scenario. Does anybody have any pointers?

Thank you again!



Addendum:

I started reading about Promises and altered the code to this:
Code:
$._urlExists = function(url_to_check) {
    $gameSystem._urlExists = false;
    // check if string  is valid url format, source: https://stackoverflow.com/a/5717133
    var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
    '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name
    '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
    '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
    '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
    '(\\#[-a-z\\d_]*)?$','i'); // fragment locator

    if (!!pattern.test(url_to_check) == true) {
        return new Promise(function(resolve, reject) {
            var reader = new XMLHttpRequest();
            reader.open('get', url_to_check, true);
            reader.onreadystatechange = (function() {
                if (reader.readyState === 4) {
                    //check to see whether request for the file failed or succeeded
                    if ((reader.status == 200) || (reader.status == 0)) {
                        return resolve(true);
                    } else {
                        return resolve(false);
                    };
                };
            });
            reader.send(null);
        });
    };
};

Which seems to work, I just need to figure out how to parse the returned value... it's like a weird object:

aa9269.png


Addendum 2:

It's not pretty or elegant, but this is how I got it to work in my Game Boot:
Code:
var _Scene_Boot_start = Scene_Boot.prototype.start;
    Scene_Boot.prototype.start = function() {
        _Scene_Boot_start.call(this);
        // get ip lookup services list
        var ip_lookup_url = $._ipLookupServicesURL();
        console.log(ip_lookup_url);
        var url_exists = $._urlExists(ip_lookup_url);
        console.log(url_exists);
        url_exists.then(function(value) {
          console.log(value);
          if (value === true) {
            var ip_lookup_json = $._getIPLookupServices(ip_lookup_url);
             console.log(ip_lookup_json);
            ip_lookup_json.then(function(json_data) {
              console.log(json_data);
              $gameSystem._IPLookupJSON = json_data;
            });
          };
        });
    };
 
Last edited:

Kes

Veteran
Veteran
Joined
Aug 3, 2012
Messages
22,480
Reaction score
11,950
First Language
English
Primarily Uses
RMVXA
[closed]IgnoreMe[/closed]
 
Status
Not open for further replies.

Latest Threads

Latest Posts

Latest Profile Posts

Artists out there, is there something RPG maker related you wish your graphics software had but doesn't? (Something like automatically transform a wall tile into a cylindrical tower). I want to give a boost to WecTools, but I'm dry of ideas right now...
having anxiety during all this virus stuff is the absolute worst. I'm the only one missing out on my friend's wedding in Sept. because I can't be in large groups of people anymore due to anxiety.
Well... I just spent most of the day making something I cant even use xD

Hero_1.png
The idea was to look at the original but at a medium distance.
In hindsight, I might as well have just edited the original lol... I didn't intend for it to end up so similar.
does anyone else feel tired after completing a sprite?

Forum statistics

Threads
113,906
Messages
1,078,338
Members
148,011
Latest member
minh0408
Top