1

I am trying to get the scroll position using the following code:

    useEffect (()=>{
    document.addEventListener("scroll", e => {
        let scrolled = document.scrollingElement.scrollTop;
        if (scrolled >= 5){
           setPos("moved")
        } else {
           setPos("top")
        }
    })
  },[])

Typescript complains about the document.scrollingElement.scrollTop saying that it is possibly null. How do I avoid this error and keep typescript happy?

bobypoz
  • 41
  • 1
  • 8

3 Answers3

2

There are at least two ways.

  1. interrupt function if the element doesn't exist
document.addEventListener("scroll", e => {
  if (!document.scrollingElement) {
    return;
  }

  let scrolled = document.scrollingElement.scrollTop;
  ...
});
  1. Check with exclamation mark operation:
document.addEventListener("scroll", e => {
  let scrolled = document.scrollingElement!.scrollTop;
  ...
});
Samuli Hakoniemi
  • 18,740
  • 1
  • 61
  • 74
  • Exclamation mark solves the issue! Thanks – bobypoz Jan 13 '21 at 08:14
  • 3
    @bobypoz You should (in theory) almost never use exclamation mark operator because why would something be nullable in the first place if it's expected to always have non-null value. This means that if scrollingElement is nullable, it can obviously be null in some cases, and in those cases exclamation operator will cause runtime errors and your app might crash. – zhuber Jan 13 '21 at 08:29
0

Just do a null check

useEffect(() => {
  document.addEventListener("scroll", e => {
    if (document.scrollingElement !== null) {
      const scrolled = document.scrollingElement.scrollTop;
      if (scrolled >= 5) {
        setPos("moved")
      } else {
        setPos("top")
      }
    }
  })
}, [])
zhuber
  • 5,364
  • 3
  • 30
  • 63
  • 1
    TS still complains. Exclamation mark solution suggested above works. – bobypoz Jan 13 '21 at 08:15
  • I was not aware that scrollingElement is nullable (thought it was scrollTop) - Please see edited answer, because using exclamation mark force unwraps value, and although it "fixes" your TS errors, if scrollingElement is null you'll get runtime error which obviously shouldn't happen. – zhuber Jan 13 '21 at 08:26
0

I find a null check guard clause the best way.

useEffect (()=>{
   document.addEventListener("scroll", e => {
   let scrolled = document.scrollingElement.scrollTop;
   if (scrolled === null) {
      return;
   }
   if (scrolled >= 5){
      setPos("moved")
   } else {
      setPos("top")
    }
 })
},[])
Henry Boisdequin
  • 325
  • 1
  • 3
  • 9