The "Is this a word" check of my Phase 1 Flatiron Project
Published: 2023-11-13 22:56:13

## Hello!

I thought I'd break apart my "isAWord" function in my project as this is where all of the magic happens.

My project can be found here: `https://github.com/Hroney/flatiron-phase-1-project`
## The Object

For reference: The Object that is the word and its functions are seen here.
```
class Word {
    constructor(name) {
        this.name = name;
        this.definitions = [];
        this.nameArray = [];
    }

    addDefinition(definition, partOfSpeech) {
        this.definitions.push({ definition, partOfSpeech });
    }

    splitTheWord() {
        this.nameArray = this.name.toUpperCase().split('');
    }
}
```


## The Function

We start off by creating an `Async` function as `isAWord` calls the dictionary api multiple times while writing information to a `db.json`.

The passed in `userInput` is grabbed from an event listener text input and put to lowercase to standardize the usage.
```
async function isAWord(userInput) {
    let word = userInput.toLowerCase();
    ...
```
Next the user input `word` is checked against the `db.json` and pulls the relevant data instead of calling the dictionary api a second time for information we've already gathered.

Each definition and the related `partOfSpeech` in the `db` is grabbed and is passed into the object `theWord` 

`theWord` is split using `splitTheWord` which turns the name of `theWord` into an array so each letter can be appended to it's own `Div`.
```
   if (db && word in db) {
        const dbWord = db[word];
        theWord = new Word(dbWord.name);
        dbWord.definitions.forEach(({ definition, partOfSpeech }) => {
            theWord.addDefinition(definition, partOfSpeech);
        });
        theWord.splitTheWord();
        return theWord;
    }
```
If the word is not in the `db.json` it is checked first to make sure it is a word.

This function checks the passed in `userInput` and determines if any of the elements in the `userInput` are themselves a space, a punctuation mark, or a number. All of which would not return a proper word.

The `returnValue` defaults `true` as to assume it's a valid word until proven otherwise.
```
function isASingleWord(userInput) {
    let charArray = userInput.split('');
    const punctuation = /[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]/;
    const numbers = /\d+/g;
    let returnValue = true;

    if (charArray.some(element => element.includes(' '))) {
        returnValue = false;
    } else if (charArray.some(element => punctuation.test(element))) {
        returnValue = false;
    } else if (charArray.some(element => numbers.test(element))) {
        returnValue = false;
    }
    return returnValue;
}
```

Once the word passes the `isASingleWord` if statement, the dictionary api is called.

The `response` variable is created and assigned the fetched status. If the response is `ok` (a read only property of response) and it's boolean returns false, the api call was unsuccessful.
```
const response = await fetch(apiUrl);
            if (!response.ok) {
                throw new Error(`HTTP Error! Status is: ${response.status}`);
            }
```

If it passes as true however, the `data` variable is assigned the response passed through the built in `json()` function.

This `data` is checked for the title of the word and if the title returns `No Definitions Found` then while it is a word, it is not a definable word in the dictionary and will return an empty object Word.
```
try {
     const data = await response.json();
            if (data.title === "No Definitions Found") {
                return new Word('');
            }
```
If however it does have a title that isn't the api's default `No Definitions Found`, then `theWord` is instantiated with the `word` data from the api call. The definitions and parts of speech are grabbed and build the object.

It is then added to the database with the `addToDB` function so that successive api calls do not call words already added to the `db.json`.

```
            else {
                theWord = new Word(data[0].word);
                data[0].meanings.forEach(object => {
                    object.definitions.forEach(definitionArray => {
                        theWord.addDefinition(definitionArray.definition, object.partOfSpeech);
                    });
                });
                theWord.splitTheWord();
                addToDB(theWord);
                return theWord;
            }
```

Lastly, the `try-catch` block is finished, where the catch grabs an `error` if one exists and if the `isASingleWord` function returns false, it fires the `else` statement to return an empty `Word Object` to clear out the gamefield. 
```
catch (error) {
            console.error('Error fetching word data:', error);
            return new Word('');
        }
    } else {
        return new Word('');
    }
```

This project was a lot of fun and I learned a lot about `async` and `promise` and yet, I feel as though I have so much to learn on the subject. 

Thank you if you stuck with me! I'm sure there's a better way to do the project I've created as I essentially brute forced my way through on the API calls, my Json-server crashes often I believe because of my anti-virus, and the async functions often are slow. I look forward to challenging myself and learning to know what I did wrong where how to improve.