Search code examples
javascriptreactjsconditional-operator

Function returning Promise in ternary expression not working React


I have a function called permCheck() which will resolve to true or false based on some logic. I need to take the value from this and utilize it in a ternary expression to change the content the user sees. However, it seems to always be returning the true part of the expression, even when permCheck() is false.

Here is the permCheck() function which does properly return true or false:

function permCheck(res) {
  let isMember;
  return axios.get(window.location.origin + "/username").then((res) => {
    axios
      .get(
        "https://api.endpoint.com/ismember/" +
          res.data
      )
      .then((res) => {
        return res.data; // This will be true or false
      });
    isMember = res.data;
    return isMember;
  });
}

Then in the return for my react app I am trying to change the content based on the permCheck function. This is where it seems to always just default to the first part of the ternary expression. As you can see I even have a console.log in the ternary expression which is properly returning true or false.

return (
<div className="ui">
  <AppLayout
    content={
      permCheck().then((a) => {
        console.log("IN TERNARY: " + a);
        Promise.resolve(a);
      })
        ? appContent
        : accessDenied
    } // Here we expect true or false from permCheck()
    navigation={<ServiceNavigation />}
    notifications={<FlashMessage />}
    breadcrumbs={<Breadcrumbs />}
    contentType="table"
    tools={Tools}
    headerSelector="#navbar"
    stickyNotifications={true}
  />
</div>

);


Solution

  • You can't check for a value, that you will only receive in the future, so you can't just unwrap your promise.

    Instead, you should use a state variable to store the result, and rerender your component, once it's available. Until then, you can render some loading effect/spinner/text, to inform the user.

    Assuming you're using a functional component, it'd look like this:

    function component(){
      const [permission, setPermission] = useState(undefined)
      //Use `useEffect` to prevent recurring checking
      useEffect(() => {
        permCheck().then((a) => {
          //Update (rerender) the component with the permission info
          setPermission(a)
        })
      }, [])
      return (
      <div className="UI">
        <AppLayout
          content={
            //When this runs for the first time, `permission` will be `undefined` (meaning 'not available'), so handle this case as well:
            permission === undefined
              ? 'Checking permission, hang on...'
              : permission
                ? appContent
                : accessDenied
          }
          navigation={<ServiceNavigation />}
          notifications={<FlashMessage />}
          breadcrumbs={<Breadcrumbs />}
          contentType="table"
          tools={Tools}
          headerSelector="#navbar"
          stickyNotifications={true}
        />
      </div>
      )
    }