1

I wrote a function that returns a day of the week given a number (1 = Monday, 2 = Tuesday etc) and I was supposed to create a caveat where if the number was less than 1 or greater than 7, the function should return null. Why is it instead returning undefined for 0 and 8?

daysOfWeek = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

function returnDay(day) {
  day = daysOfWeek[day - 1];
  if (day > 7 || day < 1) {
    return null
  } else {
    return day
  }
}

console.log(returnDay(8))
console.log(returnDay(0))

6
  • Maybe the item of daysOfWeek at index day - 1 is undefined? May you share an example where you call the function, along with an example of daysOfWeek? Commented Apr 21, 2021 at 16:43
  • Please add daysOfWeek to the question. Commented Apr 21, 2021 at 16:44
  • day = daysOfWeek[day-1]; You're overwriting day, so it's no longer going to be a number after this point. So the check on the line after this isn't going to work as you expect it to. Commented Apr 21, 2021 at 16:44
  • 3
    You are re-assigning to day before checking whether the input is valid. Commented Apr 21, 2021 at 16:44
  • 1
    note the very first thing you do in your function, before your if Commented Apr 21, 2021 at 16:45

3 Answers 3

3

You are overwriting your argument, which is considered bad practice.

When you access daysOfWeek[0 -1] => daysOfWeek[-1] => undefined, you then evaluate is undefined < 1 which is falsy. So you enter the else, which returns day => undefined

The below code works

daysOfWeek = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

function returnDay(day) {
  if (day <= 7 && day >= 1) {
    return daysOfWeek[day - 1]
  }
  return null
}

console.log(returnDay(8))
console.log(returnDay(0))

Or, even more dense

daysOfWeek = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

function returnDay = d => daysOfWeek[d - 1] || null

console.log(returnDay(8))
console.log(returnDay(0))
Sign up to request clarification or add additional context in comments.

6 Comments

The same issue here. What if daysOfWeek size change for some reason? You'll have to adjust two things in your code, not one. And yes, another good point was just given in the answer the OP gave.
Another note, when you have multiple variables that represent the a similar concept, it helps it distinguish them in the variable name. In this case 'dayIndex' and 'dayTitle` would work well, it helps avoid the headache you are having here
@raina77ow I do not expect the days of the week to change anytime soon. However in principle you are correct, and it would be better to reference the daysOfWeek.length. For that matter, this works but it's less obvious why it works for a beginner. day => daysOfWeek[day-1] || null
It works, because it tries to fetch a title for given day - and gives a default value if fetch failed. That's as straightforward as it can be. Checking against range is error-prone by definition; one example was just given in the OP's post.
We're splitting hairs at this point, but I do not think short-circuit evaluations is the best way to teach a new developer. Maybe you think it is, that's fine.
|
1

Basically, you have two range checks in your code right now, and that's the biggest issue.

Here's the first check:

day = daysOfWeek[day - 1];

... which ends with undefined unless day has valid value (so that there's an element in daysOfWeek that corresponds to that value).

And here's the second check:

if (day > 7 || day < 1) { ... }

... which ends up doing wrong things because day variable gets a different value in that line of the first check. You can fix this, of course, by introducing another name...

const dayTitle = daysOfWeek[day - 1];
if (day > 7 || day < 1) { ... }

... but that means you're still checking the same condition twice. And it's never a good idea to repeat yourself.

So here's how it can be done:

function returnDay(day) {
  return daysOfWeek[day - 1] || null;
}

... yep, that simple: the boundary range check now is done by JS, not you and your code. In other words, if day value cannot be used as a proper index for that dayOfWeek array, you'll just get undefined (which will be coalesced by || null to, well, null).

And yes, having null as kind of default value in this case seems weird to me.

Comments

-1

So I changed the arguement so that day is no longer being overwritten and it looks like this:

function returnDay(n){
    day = daysOfWeek[n-1];
    if (n  > 7 || n  < 1){
        return null
    } else {
        return day
    }
}
console.log(returnDay(8))
console.log(returnDay(0))

I now successfully get null for returnDay(0) and returnDay(8)

2 Comments

Indexes in JS start with 0, not 1; there's no element for day[7]. But that's actually another good point why checking range explicitly is bad.
Both of the other answers are better because they explain what's going on and why it should be changed. - Remember, SO isn't here just to help you, but to also help others with similar issues.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.