RMMV If an array object does not exist in an if statement, don't report error, just continue

Status
Not open for further replies.

bishiba

Adept
Veteran
Joined
Apr 6, 2016
Messages
278
Reaction score
161
First Language
Swedish
Primarily Uses
N/A
Is there anyway without using "try" to perform the below line, where it doesn't fail if filter doesn't return a weapon?
JavaScript:
for (var i = 1; i < 8; i++) if ($gameActors.actor(i).weapons().filter(weapon => weapon.name == $dataWeapons[21].name)[0].name) {true} else {false}

The error is as follows, I naturally know what it means, but I'll include it anyways.
JavaScript:
Uncaught TypeError: Cannot read property 'name' of undefined
    at <anonymous>:1:93

I am looking for something along the lines of if (€Array.name), where "€" would essentially imply if does not exist, just continue. I know € does not exist, it's an example.

Edit:
I thought the following might work, but yeah, as I feared, even though the try statement is within the loop, it does break the loop.
JavaScript:
for (var i = 1; i < 8; i++) try {if ($gameActors.actor(i).weapons().filter(weapon => weapon.name == $dataWeapons[21].name)[0].name) {true} else {false} } catch(e) {console.error(e)}

Best regards,
Bishiba
 
Last edited:

KurayamiBlackheart

Phoenix of darkness.
Veteran
Joined
Sep 4, 2019
Messages
173
Reaction score
137
First Language
French
Primarily Uses
RMMV
When it fails, it's because the actor doesn't have an equipment right ? So it can't read the variables of a weapon null. You should just check if the actor(i) have an equipment before trying to filter it if it's the case. Thus preventing you from getting that error.

EDIT : What about this ?

Code:
for (var i = 1; i < 8; i++) {
    var wcheck = $gameActors.actor(i).weapons().filter(weapon => weapon.name == $dataWeapons[21].name);
    if (wcheck[0] && wcheck[0].name) {
        true;
    } else {
        false;
    }
}

or if you want everything on one line :
Code:
for (var i = 1; i < 8; i++) if ($gameActors.actor(i).weapons().filter(weapon => weapon.name == $dataWeapons[21].name)[0] && $gameActors.actor(i).weapons().filter(weapon => weapon.name == $dataWeapons[21].name)[0].name) {true} else {false}
 
Last edited:

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
4,969
Reaction score
4,553
First Language
English
Primarily Uses
RMMZ
Use the hasWeapon function instead.

JavaScript:
for (const actor of $gameActors) { if (actor.hasWeapon($dataWeapons[21]) { true } else { false } }

But if you absolutely must use that construction, upgrading to a version of nwjs that supports ES6 will allow you to use null-chaining operators:

JavaScript:
for (var i = 1; i < 8; i++) if ($gameActors.actor(i).weapons()?.filter(weapon => weapon === $dataWeapons[21])[0]) {true} else {false}

Failing that, as Shaden said you'll need to check there's a value there first before filtering it.

Code:
for (var i = 1; i < 8; i++) {
  var weapons = $gameActors.actor(i).weapons().filter(weapon -> weapon === $dataWeapons[21]);
  if (weapons.length > 0) { true } else { false }
}
 

KurayamiBlackheart

Phoenix of darkness.
Veteran
Joined
Sep 4, 2019
Messages
173
Reaction score
137
First Language
French
Primarily Uses
RMMV
Use the hasWeapon function instead.

JavaScript:
for (const actor of $gameActors) { if (actor.hasWeapon($dataWeapons[21]) { true } else { false } }

But if you absolutely must use that construction, upgrading to a version of nwjs that supports ES6 will allow you to use null-chaining operators:

JavaScript:
for (var i = 1; i < 8; i++) if ($gameActors.actor(i).weapons()?.filter(weapon => weapon === $dataWeapons[21])[0]) {true} else {false}

Failing that, as Shaden said you'll need to check there's a value there first before filtering it.

Code:
for (var i = 1; i < 8; i++) {
  var weapons - $gameActors.actor(i).weapons();
  if (weapons) {
    if (weapons.filter(weapon -> weapon === $dataWeapons[21])[0]) { true } else { false }
  }
}
1642530236535.png
Little typo,
var weapons = ...
not var weapons - ... :kaohi:

EDIT : Also I'm pretty sure OP wants to do something with the name of the weapon or something. Tho it might be helpful to know what you're really trying to do with the code to begin with @bishiba.
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
4,969
Reaction score
4,553
First Language
English
Primarily Uses
RMMZ
It may well be that they're trying to do something with the name, but all the condition is currently checking is whether the weapon *has* a matching one, which I presume is just checking whether they have a given weapon equipped. But you're right, need more information on what they're trying to do.
 

bishiba

Adept
Veteran
Joined
Apr 6, 2016
Messages
278
Reaction score
161
First Language
Swedish
Primarily Uses
N/A
Use the hasWeapon function instead.

JavaScript:
for (const actor of $gameActors) { if (actor.hasWeapon($dataWeapons[21]) { true } else { false } }

But if you absolutely must use that construction, upgrading to a version of nwjs that supports ES6 will allow you to use null-chaining operators:

JavaScript:
for (var i = 1; i < 8; i++) if ($gameActors.actor(i).weapons()?.filter(weapon => weapon === $dataWeapons[21])[0]) {true} else {false}

Failing that, as Shaden said you'll need to check there's a value there first before filtering it.

Code:
for (var i = 1; i < 8; i++) {
  var weapons = $gameActors.actor(i).weapons().filter(weapon -> weapon === $dataWeapons[21]);
  if (weapons.length > 0) { true } else { false }
}
I have independent items, it won't be item 21. That's why I do it this way. I'm comparing it to the base item.

The way I normally do something like this would be like below:
JavaScript:
for (var i = 1; i < 8; i++) try {
    if ($gameActors.actor(i).weapons().filter(weapon => weapon.name == $dataWeapons[21].name)[0]) {
        if ($gameActors.actor(i).weapons().filter(weapon => weapon.name == $dataWeapons[21].name)[0].name) {
            console.log(true)
        } else {
            console.log(false)
        }
    }
} catch(e) {console.error(e)}

But yeah, thanks! :) I remembered seeing something about the "?" thing from Web dev simplified on youtube some time ago. I figured it might be pertinent to my issue. I'm running nwjs 49.2 so it does work with the below:

JavaScript:
for (var i = 1; i < 8; i++) if ($gameActors.actor(i).weapons()?.filter(weapon => weapon.name == $dataWeapons[21].name)[0]) {console.log(true)} else {console.log(false)}

When it fails, it's because the actor doesn't have an equipment right ? So it can't read the variables of a weapon null. You should just check if the actor(i) have an equipment before trying to filter it if it's the case. Thus preventing you from getting that error.

EDIT : What about this ?

Code:
for (var i = 1; i < 8; i++) {
    var wcheck = $gameActors.actor(i).weapons().filter(weapon => weapon.name == $dataWeapons[21].name);
    if (wcheck[0] && wcheck[0].name) {
        true;
    } else {
        false;
    }
}

or if you want everything on one line :
Code:
for (var i = 1; i < 8; i++) if ($gameActors.actor(i).weapons().filter(weapon => weapon.name == $dataWeapons[21].name)[0] && $gameActors.actor(i).weapons().filter(weapon => weapon.name == $dataWeapons[21].name)[0].name) {true} else {false}
Indeed that's how I would normally do it, but it requires, as you know, an extra check. Luckily I had upgraded to 49.2 so I could use the null-chaining. And nah, it was just one line as it was just one statement, you can see above how I normally perform the pre-check. :p

Also, it doesn't fail because the actor doesn't have equipment, it fails because the filter doesn't return an equipment with the required name. It has to be the name "Wraithbane", if not it returns an empty array, which is why [0] doesn't have a name property :)

Thanks a lot to both of you! :)
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
4,969
Reaction score
4,553
First Language
English
Primarily Uses
RMMZ
I have independent items, it won't be item 21. That's why I do it this way. I'm comparing it to the base item.

The way I normally do something like this would be like below:
JavaScript:
for (var i = 1; i < 8; i++) try {
    if ($gameActors.actor(i).weapons().filter(weapon => weapon.name == $dataWeapons[21].name)[0]) {
        if ($gameActors.actor(i).weapons().filter(weapon => weapon.name == $dataWeapons[21].name)[0].name) {
            console.log(true)
        } else {
            console.log(false)
        }
    }
} catch(e) {console.error(e)}

But yeah, thanks! :) I remembered seeing something about the "?" thing from Web dev simplified on youtube some time ago. I figured it might be pertinent to my issue. I'm running nwjs 49.2 so it does work with the below:

JavaScript:
for (var i = 1; i < 8; i++) if ($gameActors.actor(i).weapons()?.filter(weapon => weapon.name == $dataWeapons[21].name)[0]) {console.log(true)} else {console.log(false)}


Indeed that's how I would normally do it, but it requires, as you know, an extra check. Luckily I had upgraded to 49.2 so I could use the null-chaining. And nah, it was just one line as it was just one statement, you can see above how I normally perform the pre-check. :p

Also, it doesn't fail because the actor doesn't have equipment, it fails because the filter doesn't return an equipment with the required name. It has to be the name "Wraithbane", if not it returns an empty array, which is why [0] doesn't have a name property :)

Thanks a lot to both of you! :)
Why not use baseItemId instead of name?
 

bishiba

Adept
Veteran
Joined
Apr 6, 2016
Messages
278
Reaction score
161
First Language
Swedish
Primarily Uses
N/A
No problem, glad you could solve your issue ! :kaohi:
Yeah, this feature will be useful for so many things :p


Why not use baseItemId instead of name?
Well, I knew there is a property for that, as the conditional branch game interpreter returns true if checked. But I just wrote this quickly as I knew the property name.

Now this is how you screw over a boss which is looking for a weapon that you have ;) And as per the recommendation I'm using baseItemId, I suppose it does save a few characters of code :)

JavaScript:
for (var i = 1; i < 8; i++) if ($gameActors.actor(i).weapons()?.filter(weapon => weapon.baseItemId == 21)[0]) {
    $gameMessage._faceName = $gameActors.actor(i)._faceName;
    $gameMessage._faceIndex = $gameActors.actor(i)._faceIndex;
    $gameMessage._texts[0] = "Would this be the blade you're longing after?"
}
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
4,969
Reaction score
4,553
First Language
English
Primarily Uses
RMMZ
Yeah, this feature will be useful for so many things :p



Well, I knew there is a property for that, as the conditional branch game interpreter returns true if checked. But I just wrote this quickly as I knew the property name.

Now this is how you screw over a boss which is looking for a weapon that you have ;) And as per the recommendation I'm using baseItemId, I suppose it does save a few characters of code :)

JavaScript:
for (var i = 1; i < 8; i++) if ($gameActors.actor(i).weapons()?.filter(weapon => weapon.baseItemId == 21)[0]) {
    $gameMessage._faceName = $gameActors.actor(i)._faceName;
    $gameMessage._faceIndex = $gameActors.actor(i)._faceIndex;
    $gameMessage._texts[0] = "Would this be the blade you're longing after?"
}
If you want to streamline it even more, you could do

if (Array.from({length: 8}, (_, i) => i + 1).some(id => $gameActors.actor(id).weapons().filter(weapon => weapon.baseItemId === 21)).length > 0)
 

KurayamiBlackheart

Phoenix of darkness.
Veteran
Joined
Sep 4, 2019
Messages
173
Reaction score
137
First Language
French
Primarily Uses
RMMV
If you want to streamline it even more, you could do

if (Array.from({length: 8}, (_, i) => i + 1).some(id => $gameActors.actor(id).weapons().filter(weapon => weapon.baseItemId === 21)).length > 0)
You're going full hardcore like if it's an essay :kaoswt2: I didn't even know the function Array.some() from JavaScript, we learn some everyday.
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
4,969
Reaction score
4,553
First Language
English
Primarily Uses
RMMZ
You're going full hardcore like if it's an essay :kaoswt2: I didn't even know the function Array.some() from JavaScript, we learn some everyday.
You have no idea how obsessive I get with refactoring code snippets. :p
 

bishiba

Adept
Veteran
Joined
Apr 6, 2016
Messages
278
Reaction score
161
First Language
Swedish
Primarily Uses
N/A
If you want to streamline it even more, you could do

if (Array.from({length: 8}, (_, i) => i + 1).some(id => $gameActors.actor(id).weapons().filter(weapon => weapon.baseItemId === 21)).length > 0)
Hm... Is it more efficint in terms of processing power? Because it's actually longer than the thing I'm using :/

Haha, yeah, refactoring code is really fun, but it can get you stuck on something that you could do really easily xD Like I didn't need to do what I did just now, but it just gives me so much pleasure learning these new things :p
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
4,969
Reaction score
4,553
First Language
English
Primarily Uses
RMMZ
Hm... Is it more efficint in terms of processing power? Because it's actually longer than the thing I'm using :/
I think .some is faster than a for loop, yes.
 

KurayamiBlackheart

Phoenix of darkness.
Veteran
Joined
Sep 4, 2019
Messages
173
Reaction score
137
First Language
French
Primarily Uses
RMMV
Hm... Is it more efficint in terms of processing power? Because it's actually longer than the thing I'm using :/
the length of a code doesn't determine its speed. also yes in theory it should be faster, but at this point it's insignificant because the code barely did take alot of processing power to begin with !
 

bishiba

Adept
Veteran
Joined
Apr 6, 2016
Messages
278
Reaction score
161
First Language
Swedish
Primarily Uses
N/A
I think .some is faster than a for loop, yes.
I should've tried with hasWeapon... I guess Yanfly changed the hasWeapon code to confer with baseItemId, don't know why I didn't verify that lol >.<
Code:
Yanfly.Item.Game_Actor_hasWeapon = Game_Actor.prototype.hasWeapon;
Game_Actor.prototype.hasWeapon = function(weapon) {
    if (this.hasBaseItem(weapon)) return true;
    return Yanfly.Item.Game_Actor_hasWeapon.call(this, weapon);
};

the length of a code doesn't determine its speed. also yes in theory it should be faster, but at this point it's insignificant because the code barely did take alot of processing power to begin with !
I'm aware that the length of code doesn't determine speed, is why I asked if it was faster :p And yes, this code runs in such a fraction of a fraction of a fraction of time, but still good to know that some() would be quicker than a loop. I expected as such, but again, good to confirm :)

Truth is however, that I should delve into using some at any rate, I used it once to allow anyone using my plugins to automatically check if an update exists. And it was hell to learn, but very neat when it was done.
JavaScript:
        var ClientPlugins = BISH.Plugins;
        var ServerPlugins = pluginScript(iframe.contentDocument);
        var MismatchedVersions = ServerPlugins.filter(serverPlugins  =>
            BISH.Plugins.some(
                activePlugins  =>
                serverPlugins.name === activePlugins.name &&
                serverPlugins.version !== activePlugins.version
            )
        );
 
Last edited:

KurayamiBlackheart

Phoenix of darkness.
Veteran
Joined
Sep 4, 2019
Messages
173
Reaction score
137
First Language
French
Primarily Uses
RMMV
I should've tried with hasWeapon... I guess Yanfly changed the hasWeapon code to confer with baseItemId, don't know why I didn't verify that lol >.<
Code:
Yanfly.Item.Game_Actor_hasWeapon = Game_Actor.prototype.hasWeapon;
Game_Actor.prototype.hasWeapon = function(weapon) {
    if (this.hasBaseItem(weapon)) return true;
    return Yanfly.Item.Game_Actor_hasWeapon.call(this, weapon);
};


I'm aware that the length of code doesn't determine speed, is why I asked if it was faster :p And yes, this code runs in such a fraction of a fraction of a fraction of time, but still good to know that some() would be quicker than a loop. I expected as such, but again, good to confirm :)
oh yeah Yanfly thinks about alot of things, very professionnal in his code. I had to fix alot of plugins (incompatibilities or just bugs like memory leaks and not functionning plugins) and if I recall I'm pretty sure I never had to fix a plugin from Yanfly.
 

bishiba

Adept
Veteran
Joined
Apr 6, 2016
Messages
278
Reaction score
161
First Language
Swedish
Primarily Uses
N/A
oh yeah Yanfly thinks about alot of things, very professionnal in his code. I had to fix alot of plugins (incompatibilities or just bugs like memory leaks and not functionning plugins) and if I recall I'm pretty sure I never had to fix a plugin from Yanfly.
Well, I've encountered some issues, I even made one of the issues I had into an actual plugin.
Then again I have some 80 plugins active xD With a big portion of that being my own plugins :p
1642534999620.png

But yes, Yanfly is very adept. Yet everyone does make mistakes, especially in programming, and when you consider Yanfly's immense scope of plugins it's very obvious there will be some problems every once in a while :)
 

bishiba

Adept
Veteran
Joined
Apr 6, 2016
Messages
278
Reaction score
161
First Language
Swedish
Primarily Uses
N/A
If you want to streamline it even more, you could do

if (Array.from({length: 8}, (_, i) => i + 1).some(id => $gameActors.actor(id).weapons().filter(weapon => weapon.baseItemId === 21)).length > 0)
What about this then? :p

JavaScript:
$gameParty.members().some(member => member.hasWeapon($dataWeapons[21]))

Edit:
Oops, apologies for double posting :(
 
Status
Not open for further replies.

Latest Threads

Latest Posts

Latest Profile Posts

What?! You want 2 more hours of a playthrough? Well you got it! Come hang out with us while we dive even deeper into the awesome game Kindred Novel by BirdBunch! :LZSjoy:
Well, shoot. I didn't mean for the title screen to be there in my previous post.
Can everyone here just forget about that until I'm actually ready to formally announce it?
No idea what do do with this space, nor how to fill it even if I did xD
smg.PNG
Making progress. And simplifying.
jV7qfoy.gif
Not sure why I'm a jack of all trades , master of none... Sigh. Album out 06/03/2022 on all ur favorite platforms. 10 tracks.

Forum statistics

Threads
122,067
Messages
1,146,244
Members
160,343
Latest member
Okiee
Top