So previously I have been using this following code to check if a member had a certain role.
if (message.member.roles.some(role => role.name === 'role'))
It always used to work for me. However, now it seems to return an error. I have narrowed it down, to message.member returning Null. I have tried changing it guildMember and the same issue.
the error in question is:
TypeError: Cannot read property 'roles' of undefined
Has there been any changes to this?
Can someone help me try to find a new way to check if they have a role?
Edit
This is where the message comes from
client.on('message', message => {
console.log("Member: " + message.member);
This returns null favlues for message.member.
Edit:
I've seen the console log for the 'message' object that you have shared in the comment and below is my update from that:
As we can see from the below image, message.member is 'null' due to which you were getting the error that you cannot find the property 'roles' of undefined (member which is null here).
I believe what you are looking for here is message.guild.roles here which is a collection (Map). Please see the screenshot below.
You should try to retrieve this roles Map and iterate over it for the in the following way:
const roles = message.guild.roles;
You can then use roles.entries() in order to get the key-value pairs from the roles MAP and iterate over them and use the if condition that you were initially using.
Like the error message states, this is happening because 'member' is undefined. You can either have a guard clause like mentioned by user Paulquappe in his answer, but the guard clause would be for member and not roles, so something like this:
if (message.member && message.member.roles.some(role => role.name === 'role'))
or, if you are going to transpile your code, you can use optional chaining from ES2020 (this is a very new feature in JS, therefore I would not recommend it unless you are going to transpile your code):
The optional chaining operator acts like a guard clause, but the syntax only requires that you use a '?' before chaining using the dot syntax.
if (message.member?.roles.some(role => role.name === 'role'))
Most likely there is no 'roles' prop on member. I suggest you create a guard clause and ensure the props is there before accesing it.
You can read about guard clause here:
How do you implement a guard clause in JavaScript?
i succesfully do this inside my templates
this.destinyForm.get('category').value?.includes('male')
Note the value?.includes with the safe type operator as the form may not have a value, but when i use the same piece of code in the component.ts i get:
Module parse failed: Unexpected token
You may need an appropriate loader to handle this file type.
Any ideas?
?. is a feature of Angular templating, and is not a part of TypeScript - the two have very similar syntax, but there are some differences, and this is one of them. That means you can't use it in your component code. A couple of other ways to do what you want:
The standard way would be to use short-circuit logic to check the possibly missing parts, e.g.
this.destinyForm.get('category').value &&
this.destinyForm.get('category').value.includes('male')
If value is null or undefined, it will return that and not attempt to read the remaining properties. (note - if get() has side effects, you'll probably want to call it and store the result in a variable first if you're using this method)
A shortcut that I use in my own app is to use a function to safely access values:
function getSafe<T> (func: () => T): T {
try {
return func()
} catch {
return undefined
}
}
getSafe(() => this.destinyForm.get('category').value.includes('male'))
The way this works is that, by wrapping it in an anonymous function, it doesn't attempt to read the value until the anonymous function is unwrapped inside the try block, which will safely catch any TypeErrors if part of the chain is null/undefined. You can do the same thing with just a regular try/catch, but doing it this way means you don't have to add that to your code over and over. (note - if the value you're accessing can throw another kind of error, this will swallow it silently so make sure to handle that separately if it's important)
Why is that Object.freeze(obj) is made to fail silently when obj is mutated?
Wouldn't it be more logical to throw than error when an immutable object is mutated? Then, it would be to the user's discretion if he wants to wrap a try catch around his Object.freeze(obj). Similar to how we need to wrap JSON.parse() with try catch to avoid errors with empty strings or malformed JSON's.
I wish if the community can make a comment.
Edit after few answers and comments:
It is understood that Object.frozen() throws error in strict mode. But why is it necessary for the method to fail silently in non-strict mode?
Object.freeze() does throw, in strict mode.
In strict mode, the following program will throw any time a property is added, mutated or deleted on the frozen object.
Assume we have
'use strict'
const obj = Object.freeze({ test: true })
Error when adding a property:
obj.other = true
// TypeError: Can't add property another, object is not extensible
Mutating an existing property throws:
obj.test = false
// TypeError: Cannot assign to read only property 'test' of object '#<Object>'
Deleting a property throws:
delete obj.test
TypeError: Cannot delete property 'test' of #<Object>
If would like to understand strict mode in more detail (highly recommended) have a look at the official MDN docs for the differences.
The opinions on this topic vary - one would expect mutations of the object to throw because "you are doing something you should not be doing" while others might say that if you Object.freeze() something, you just want to prevent any modifications to it. And that you successfully accomplish. If it caused applications to crash on mutations, programmers would have no choice but to either check all objects they did not create for their frozenness or they would have to wrap all such operations in try/catch block. This is simply too much to ask.
Note about try/catch
You can avoid wrapping property manipulations in try/catch blocks simply by checking the object's temperature 😎:
if (Object.isFrozen(obj) {
// Can't touch this!
}
I think this is why modifying a frozen object fails silently,
If error is thrown, execution of code will stop. Try and catch
statements are available to handle the error. Is it okay to use try
and catch statements for every line in your code to avoid the error?
I think no
1. Unnecessary use of try and catch blocks in code
Let's say an object is frozen at some point in the flow of control. There maybe many lines in code which try to add a new property or modify the value of an existing property in the frozen object. In this scenario, if error is thrown, then you need to add try and catch blocks in all those lines of code.
2. Any number of objects can be freezed
Let's say more than one object is freezed. This will increase the need for more try and catch statements. It may lead to enclosing each line of your code with a try and catch block
I am writing an assertion library for javascript. I want the assertions to be chainable, so each assertion needs to call
return this;
so that more assertions can be run on it.
What I want to do is write a test that will check if each assertion has the return statement. I can think of two solutions for this, and I'm not sure I like either of them.
Problematic solution - in my test I can call each assertion and see if it returns a value. This is problematic because I can't know if the assertion is going to return successfully or throw an assertion error. Ideally I'd call all of the assertions in a loop so I can call them the same way.
Hacky solution - I can call .toString() on each assertion and use regex to look for the string return this in the body of the function. I suppose this would work pretty well because I could account for any amount of whitespace in the regex, but that wouldn't stop trying to work around the solution by putting the string in an unreachable branch of code such as if(!true) return this.
I think #2 is probably simpler, but I don't love it. Does anyone have any other solutions?
Edit: Sample code for how I would like to write these tests:
var assertionFns = getAssertionFns(); // actual generation process not relevant
assertionFns.forEach(function(fn){
test(fnReturnsAValue(fn));
});
function fnReturnsAValue(fn){
// What goes here?
}
function test(value){
if(!value){
// fail the test
}
}
Just to reiterate why #1 is problematic, fn will throw an AssertionError if the assertion is failed, assuming I actually execute the function.
I hope this clarifies, please let me know if it does not.
How about just checking if it doesn't return undefined? If the function just says
return;
in it, then yes, it will still return undefined. However if the function has
return false;
in it (or any other value - including objects, numbers, etc), then the following test will determine if a function has a return
function fnReturnsAValue(fn){
if (typeof(fn)=="function" && typeof(fn())!="undefined") { return true; }
return false;
}
I'd love some other opinions on what's more efficient in this code. Basically in the following code, there's a setInterval loop and I need 4 requirements to be true before the code runs in the loop. So in v.1 I wrote an if statement checking all 4. Worked fine.
Then I switched to just using try/catch, with the code I want to execute sitting in try{}. The logic was that during each loop, an exception would be generated but suppressed for each invalid condition. On the final loop where all conditions are true, the code executes and clears the interval.
Either works. I like the try/catch method because there's less conditional code that I need to write and worry about breaking. But I'm worried that try/catch is really inefficient, especially in a setInterval() loop hitting at 100ms. What are some opinions of other bright minds here on SO?
Try/Catch
var intvar = setInterval(function(){
try{
clearInterval(intvar);
jQuery('#'+nav[pageid].t1+'>a').replaceWith(jQuery('<span>'+jQuery('#'+nav[pageid].t1+'>a').text()+'</span>'));
//set display classes for nav
jQuery('#'+nav[pageid].t1).addClass('selected').find('#'+nav[pageid].t2).addClass('subselect'); //topnav
jQuery('#'+nav[pageid].t3).addClass('selected').find('#'+nav[pageid].t4).addClass('subselect'); //leftnav
}catch(err){}
},100);
IF Block
var intvar = setInterval(function(){
if(typeof jQuery == 'function' && typeof nav == 'object' && typeof pageid != 'undefined' && typeof document.getElementById('leftnav') == 'object'){
clearInterval(intvar);
jQuery('#'+nav[pageid].t1+'>a').replaceWith(jQuery('<span>'+jQuery('#'+nav[pageid].t1+'>a').text()+'</span>'));
//set display classes for nav
jQuery('#'+nav[pageid].t1).addClass('selected').find('#'+nav[pageid].t2).addClass('subselect'); //topnav
jQuery('#'+nav[pageid].t3).addClass('selected').find('#'+nav[pageid].t4).addClass('subselect'); //leftnav
}
},100);
Exceptions should be used for exceptional circumstances (i.e. things that you don't expect to happen normally). You should not, in general, use exceptions to catch something that you can test for with an if statement.
Also, from what I understand, exceptions are much more expensive than if statements.
Use the if statement. I don't know what the overhead is for a TRY/CATCH, but I suspect it's far greater than evaluating a boolean expression. To hit the TRY/CATCH you will have to: execute a statement, generate an error [with that associated overhead], log the error (presumably), made a stacktrace(presumably), and moved back into the code. Additionally, if you have to debug code near those lines the real error could get obfuscated with what you are TRY/CATCHing.
Furthermore, it's a misuse of TRY/CATCH and can make your code that much harder to read. Suppose you do this for longer or more obfuscated cases? Where might your catch end up?
This is referred to as Exception handling
EDIT: As commented below, you only take the runtime performance hit if you actually cause an exception.
The other answers are correct, try/catch is for exceptional circumstances and error handling. if conditions are for program logic. "Which is faster?" is the wrong question.
A good rule of thumb, if you're doing nothing with the exception, it's probably not an exception!
To figure out which to use, let's break down your if condition.
typeof jQuery == 'function' Is the jQuery() function defined?
typeof nav == 'object' Does the nav global variable contain an object?
typeof pageid != 'undefined' Is the pageid global variable defined?
typeof document.getElementById('leftnav') == 'object' Does the document contain a leftnav element?
The first is clearly an exception. You ain't getting far without a jQuery() function.
The second is also an exception. You're not going anywhere without a nav object.
The third is an exception. You need a pageid to do anything.
The fourth is probably logic. "Only run this code if there is a leftnav element". It's hard to tell because the rest of the code doesn't reference a leftnav element! Only the comments do, a red flag. So it's probably a programming mistake.
So I'd probably do this (with apologies if I'm butchering jQuery):
var intvar = setInterval(function() {
// If there's no leftnav element, don't do anything.
if( typeof document.getElementById('leftnav') != 'object') {
return;
}
try {
clearInterval(intvar);
jQuery('#'+nav[pageid].t1+'>a')
.replaceWith(jQuery('<span>'+jQuery('#'+nav[pageid].t1+'>a').text()+'</span>'));
//set display classes for nav
jQuery('#'+nav[pageid].t1)
.addClass('selected')
.find('#'+nav[pageid].t2)
.addClass('subselect'); //topnav
jQuery('#'+nav[pageid].t3)
.addClass('selected')
.find('#'+nav[pageid].t4)
.addClass('subselect'); //leftnav
}
catch(err) {
...do something with the error...
}
},100);
...but I'd really examine if the leftnav element check is applicable.
Finally, I can't help but comment that this "function" is working with global variables. You should instead be passing nav and pageid into the function in order to maintain encapsulation and your sanity.
I would write the following code:
var startTime = (new Date()).getTime();
for (var i=0; i < 1000; ++i) intvar();
var endTime = (new Date()).getTime();
alert("Took " + ((endTime - startTime) / 1000.0) " seconds");
Then I would try both versions of intvar and see which runs more quickly. I'd do this myself but I don't have the page layout you do so my code wouldn't work.
Some stylistic comments - it doesn't seem necessary to test that jQuery is a function. If it isn't, your webpage is likely messed up such that not running the intvar code will not help you. If you rarely expect the exceptions to be thrown, I'd use the try/catch.
For the provided example where you are wrapping a try/catch around a block of code that should always run anyway (unless if something horrible happens), it is good form to use try/catch. An analogy for you: do you always test "Is the sky Blue?" in your if statement, or would you wrap it in a try/catch that is triggered only when the sky happens to turn Green.
Use the If statement method if you are dealing with user provided input or if the chances of a function not existing is much higher due to something else happening in the code.
Keep in mind that if you don't trigger the exception you don't have any unwinding or backtracking across code. In the example the catch will only execute if something is wrong (jQuery is missing or some such thing), however the if statement method has an evaluation happening on EVERY SINGLE CALL to that function - you shouldn't do more work than you have to.
To directly answer the question, as everyone else has, the try..catch is likely going to be more expensive if there actually is an error.
To point out some additional errors in the code beyond what others have already pointed out:
These two codes are not at all equivalent. To explain, even though the codes appear to do the exact same thing, they do not.
In the case of the if() check, NONE of the code is executed. In the case of the exception handler, each line of code inside the exception handler will be executed. SO, what happens if the error occurs in the second, or the third line? Then you've got something completely different happening in your code than what you get if you check the conditions before executing any of it.
Aside from the answers given, I want to add some thoughts on this subject.
Exceptions that are unforeseen, i.e. the runtime throws an exception, should not be caught with try ... catch because you want to read the message that is thrown in the console.
Try ... catch should IMO be thrown when an exception occurs that your application can foresee in your application logic and you want to perform some custom actions when they do. I.e. you want to be descriptive about it being an exception, and it's not part of the happy flow of the application logic.
For example, you could have a method that validates user input so you could have an isValid method that returns a boolean in which case you would use if ... then.
On the other hand if your performing a certain process, and you know that a certain exception can occur that interrupts the happy flow and you want to handle this, I feel that it is better to throw an exception.
As abstract example, you could have methods that implements some business rules.
Instead of validating every business rule for validity, you could have one custom Exception containing dynamic metadata that can be thrown by each of these methods when validity is breached and handle them appropriately, and continue the happy flow otherwise.
This would translate into something like:
throw new BusinessValidationException(TAG, 'Reason for the validation');
Which IMO is much more descriptive than:
if (!checkValidityBusinessRule())
// doSomething
For a series of business rules.
As for the example, it's my humble opinion that this check shouldn't be happening in the first place and that the given checks are true by default for implementing the method.
if(typeof jQuery == 'function' && typeof nav == 'object' && typeof pageid != 'undefined' && typeof document.getElementById('leftnav') == 'object')
What it means is that you must declaratively ensure that given conditions are true before invoking the given method with side-effects, taking away the necessity to perform the checks at all.
If it so happens that one of the conditions is false, then it will throw an exception to the console, which is actually what you want because as a developer it means that something in your application logic or lifecycle is broken.
My 2 cents, I hope they make sense.