Search code examples
javascripthtmlcssgithub-pages

GitHub Pages website not running the same as when its run locally using live server


I'm currently making a small website where someone can type in an anagram and the site will return all the possible words that can be made from the anagram. Once all the words have been returned, you can click on a word to give all of its definitions.

The site works fine when I run it locally using live server, the issue is when I deploy the repository using GitHub Pages.

When run locally, when I enter a word (e.g acres), the site will return all the possible words that can be found correctly, but when I do the same using GitHub Pages, the site won't return the same. All the logic related to finding all the possible words is in my script.js file so I'm guessing the issue might be in there? The script.js file reads in a dictionary.txt file to get a bank of words and filters through them to find the words that can be made from the anagram. The script.js file also deals with fetching the definitions of a given word from an external dictionary API and adding the data to the main html file.

Here's the script.js file. Sorry if it's a bit of a mess! I'm a bit new to coding JavaScript on the front end. I've also included the index.html and style.css files in case the issue might be in one of those.

let inputElement = document.querySelector("#anagram-input");

inputElement.addEventListener("keyup", onKeyUp);

let words = [];

fetch("dictionary.txt")
  .then(res => {
    return res.text();
  })
  .then(dictionary => {
    words = dictionary.split("\n");
    for (let i = 0; i < words.length; i++) {
      words[i] = words[i].slice(0, -1);
    }
  })
  .catch(error => {
    console.log(error);
  })

function fetchDefinitions(e) {
  let chosenWord = e.target.parentElement.parentElement.firstElementChild.textContent;
  fetch(`https://wordsapiv1.p.rapidapi.com/words/${chosenWord}/definitions`, {
      "method": "GET",
      "headers": {
        "x-rapidapi-key": "API-KEY",
        "x-rapidapi-host": "wordsapiv1.p.rapidapi.com"
      }
    })
    .then(res => {
      return res.json();
    })
    .then(data => {
      let cardInnerElement = e.target.parentElement.parentElement.parentElement;
      cardInnerElement.style = "transform: rotateY(180deg)";
      let cardFrontElement = cardInnerElement.firstElementChild;
      cardFrontElement.style = "transform: rotateY(180deg)";
      addDefinitionsHTML(cardFrontElement, data);
    })
    .catch(err => {
      console.error(err);
    });
}

function addDefinitionsHTML(element, data) {
  let definitionsHTML;
  if (data.success === false || definitions.length === 0) {
    definitionsHTML = `No definition for this word is currently available. Sorry!`;
    element.lastElementChild.innerHTML = definitionsHTML;
    return;
  }
  definitionsHTML = `<p class="card-title" style="text-align: left">Definitions of ${data.word}:</p><ul>`;
  for (let i = 0; i < data.definitions.length; i++) {
    definitionsHTML += `<p style="text-align: left">${data.definitions[i].definition}</p>`;
  }
  definitionsHTML += `</ul>`;
  element.lastElementChild.innerHTML = definitionsHTML;
}

function onKeyUp(e) {
  let enteredWord = e.target.value;
  return findWordsFromAnagram(enteredWord);
}

function findWordsFromAnagram(anagram) {
  let filteredWordList = [];
  let finalWordList = [];
  anagram = anagram.toLowerCase().split("").sort();
  //filter the dictionary list by the length of the anagram
  for (let i = 0; i < words.length; i++) {
    if (words[i].length === anagram.length) {
      filteredWordList.push(words[i]);
    }
  }
  //make a copy of filteredWordList and sort all words inside alphabetically
  let sortedFilteredWordList = filteredWordList.map(x => x);
  for (let i = 0; i < sortedFilteredWordList.length; i++) {
    sortedFilteredWordList[i] = sortedFilteredWordList[i].split("").sort();
  }
  //Add any words from filteredWordList that have the same letters as anagram to finalWordList
  for (let i = 0; i < filteredWordList.length; i++) {
    let booleanTracker = true;
    for (let j = 0; j < anagram.length; j++) {
      if (sortedFilteredWordList[i][j] != anagram[j]) {
        booleanTracker = false;
      }
    }
    if (booleanTracker) {
      finalWordList.push(filteredWordList[i]);
    }
    booleanTracker = true;
  }
  return outputWordsFromAnagram(finalWordList);
}

function outputWordsFromAnagram(words) {
  let outputElement = document.querySelector("#output");
  let outputHTML = ``;
  for (let i = 0; i < words.length; i++) {
    outputHTML += `<div class="col-lg-12 col-m-12 col-sm-12 col-xs-12 mb-3 flip-card">
                                <div class="text-center flip-card-front">
                                    <div class="card border-primary flip-card-inner">
                                        <div class="card-header"><h5>${words[i]}</h5></div>
                                        <div class="card-body text-primary">
                                            <p id="definitions" class="click">Click here for its definition!<p>
                                        </div>
                                    </div>
                            </div>
                        </div>`;
  }
  outputElement.innerHTML = outputHTML;
  let definitionElements = document.querySelectorAll("#definitions");
  for (let i = 0; i < definitionElements.length; i++) {
    definitionElements[i].addEventListener("click", fetchDefinitions);
  }
}
html,
body {
  margin: 0px;
  height: 100%;
}

.click:hover {
  cursor: pointer
}

.flip-card {
  perspective: 1000px;
}


/* This container is needed to position the front and back side */

.flip-card-inner {
  position: relative;
  width: 100%;
  height: 100%;
  transition: transform 1s;
  transform-style: preserve-3d;
}


/* Position the front and back side */

.flip-card-front {
  width: 100%;
  height: 100%;
  backface-visibility: hidden;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Anagram App</title>
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
  <link rel="stylesheet" type="text/css" href="./style.css">
</head>

<body>
  <header>
    <h1 class="text-center">Anagram App</h1>
  </header>
  <div class="container">
    <div class="input-group">
      <input id="anagram-input" type="text" class="form-control" placeholder="Anagram">
    </div>
  </div>
  <div class="container mt-3">
    <div id="output" class="row">
    </div>
  </div>
  <script src="./script.js"></script>
</body>

</html>

The link to the GitHub Pages is here

I've included screenshots of the results I get from both when I type in "acres" as the anagram.

Here is the link to the GitHub repository itself

I just can't figure out why it's not working the same as the local one. Is there something that I'm missing here?


Solution

  • Reviewing the dictionary that is returned (\n separated string), I could not figure out why you were removing the last character of each word of the word array:

    for (let i = 0; i < words.length; i++) {
       words[i] = words[i].slice(0,-1);
    }
    
    

    When typing the letter 'a', that code is placing 24 'a', 24 'b', 24 'c'...24 'z' into the word array. So when attempting to find anagrams it is searching through these letter too.

    I see no apparent reason to have that code. If you remove it produces the results you expect as far as I can tell.