Search code examples
javascriptreactjsprogressive-web-apps

Function that tests if React PWA is online never returns false


I'm using ReactJS to create a progressive web app. My app needs to determine if it is able to connect to my server so that it can know how to handle submitted data. To do this, I'm trying to write a function that returns true if and only if a HEAD request to my server succeeds.

I'm using Chrome on desktop to test my app and my server is hosted on my desktop through localhost. To test my function, I've created a temporary button on my app that runs the function when I click it. I then try different combinations of network throttling settings on Chrome devtools and manually connecting & disconnecting my server. I'm expecting a positive output only when my server is connected and there is no network throttling. However, I never receive a negative output.

I don't know for sure if my methods of testing are the way to go and I'm also unsure if my approach in solving this problem is the right one. I'm open to other solutions and/or testing methods. Any thoughts?

Here is my code for my function:

const isOnline = async () => {
  if (!window.navigator.onLine) return false;

  // I use the origin to prevent CORS errors
  const url = new URL(window.location.origin);

  // Set a random search parameter to make sure no request falls back on the cache
  url.search = new URLSearchParams({
    isonline: createId(), // Returns a random string of a certain length
  });

  try {
    // HEAD request is sufficient for my needs
    const response = await axios.head(url.toString());
    console.log(response);

    // Return true if the request was valid
    if (response.status >= 200 && response.status <= 299) return true;
    else return false;
  } catch {
    return false;
  }
};

Here is my code for my button's event handler:

const onClickIsOnline = () => {
    isOnline() ? console.log('Online!') : console.log('Offline :(');
  };

Solution

  • isOnline is defined as an async function, which means the return value will always be a Promise.

    A Promise object is a truthy value, so your

    jsisOnline() ? console.log('Online!') : console.log('Offline :(');
    

    code should always end up logging Online!.

    I believe your intention is to use the value that the Promise resolves with to determine what you log. The most straightforward way of doing that would be to chain a then() to the Promise:

    jsisOnline().then(returnValue => {
      returnValue ? console.log('Online!') : console.log('Offline :(');
    });