Develop the minion translation web app
Tags: javascript, webdev, codenewbie, minions
Published: 2020-12-15 12:03:22

Through this blog, I would help you create a translation web app using HTML, CSS and JavaScript.

If you are new to these technologies, you can refer to my blogs on [HTML](https://supminn-neog.netlify.app/blog-on-html.html) & [CSS](https://supminn-neog.netlify.app/blog-on-css.html). They are pretty simple to understand and get started.

## Small steps to build a big picture

Let's take the step by step approach in building this app. First, we shall create a textbox to accept input, a button used trigger the translation and an output area to display the translated text. All 3 elements can be created as follows in HTML.

#### HTML code snippet - basic body template
```html
…
<body>
<input type="text" placeholder="Enter your message in English" id="txt-input">
<button id="btn-translate">Translate</button>
<div id="txt-output">
</div>
<script src="app.js" type="text/javascript"></script>
</body>
…
```
The above code would produce an output as follow:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ddsm591aivwx46rc9sy9.png)

We have 3 HTML elements - input tag would accept the user's input. Button tag creates a button named **"Translate"** and an empty div element which would display the translated text as output. Note that the script tag is being used to bind this HTML file with the JavaScript logic present on the file **"app.js"**. Let's implement the logic on app.js.

We would refer to input, button and output within app.js using their id values through document query selector. 

#### JavaScript code snippet - variable declaration
```javascript
var btnTranslate = document.querySelector("#btn-translate");
var textData = document.querySelector("#txt-input");
var outputData = document.querySelector("#txt-output");
var serverURL = "https://api.funtranslations.com/translate/minion.json";
```

Since we have stored each of the element's value within a variable (var), we can refer to the same throughout this app.
Now, we want the input text to be accepted and translated only when the **"Translate"** button has been clicked upon. To do so, we make use of an inbuilt function "addEventListener" which would listen to the button being "clicked".
```javascript 
btnTranslate.addEventListener("click",btnClickHandler);
```
We are passing 2 arguments to this function. The first argument, "click" asks the eventListener to execute the function "btnClickHandler" when the button is clicked. Here btnClickHandler is a callback function. A callback function is triggered/called only when an event occurs, i.e. when the "translate" button is clicked, only then this function is being called.

Before we proceed to implement the btnClickHandler function, we must understand about APIs and JSON. You may have observed the variable named "serverURL". This refers to the server's API call URL from where we obtain the translated data.

#### Defining API and JSON

**API** - __Application Programming Interface__. By the name API itself, we can decipher that it is an interface which communicates between applications. In our web app, we are connecting to [funtranslationAPI](https://api.funtranslations.com/translate/minion.json) allowing our application to communicate with the translation function. This API call returns a JSON object.

**JSON** - __JavaScript Object Notation__. As mentioned, the data is return in the form of a JavaScript Object. Hence it would have a key value pair.

Now, we must pass some text as message to this API call, else it would return the following as output:

#### Output from API call
```json
{
    "error": {
        "code": 400,
        "message": "Bad Request: text is missing."
    }
}
```
If I pass the message as __"sample text here"__, the output we receive would be shown as:
```json
{
    "success": {
        "total": 1
    },
    "contents": {
        "translated": "umplop zin aca",
        "text": "sample text here",
        "translation": "minion"
    }
}
```
Between the above 2 calls, we understand that the first call returned as an **error** whereas the second call was a **success**. It return 1 object in total with the following attributes.
* **text** - represents the input message we have passed
* **translated** - provides the translated sentence in minion language
* **translation** - this represents the language of translation being used. 
FunTranslationAPI contains a plethora of free translation APIs amongst which we have chosen minion or the banana language.

Even though we have received the desired output, we cannot display it as the same on our web app. We would need to render it as a plain text within the div element with id as txt-output. Now, we shall add the implementation to our btnClickHandler().

#### JavaScript code snippet - function implementation
```javascript
function getTranslatedURL(value) {
    return serverURL + "?text=" + value;
}

function btnClickHandler() {
    var textValue = textData.value;
    outputData.innerText = "Translation in progress..."
    fetch(getTranslatedURL(textValue))
    .then(response => response.json())
    .then(json => outputData.innerText = json.contents.translated)
    .catch(errorHandler);
}
```
As we want this app to transalate any given sentence into the minion language, the message being passed as a parameter for the API call would be different in each case. Hence we are using **getTranslatedURL** function to concatenate the text message to our server API's URL.

Within the btnClickHandler(), the input text value is gathered and stored within a new variable __"textValue"__. The output div is made to show a message that translation is in progress, reason being a client-server communication is to be made which takes a finite amount of time. The next few lines contains the main logic of sending across our input message and correspondingly display the translated message as our output.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/t28sj2y0j4x18j4e15r3.png)


### Understanding fetch call in JavaScript

> #### The Fetch API provides a JavaScript interface for accessing and manipulating parts of the HTTP pipeline, such as requests and responses.

Let's break this down in simple terms using the above code. We pass the function __getTranslatedURL__ along with the input message __textValue__ to this **fetch** API. 
Whatever is the outcome of this function call would be **then** taken in as a __"response"__. 
This response is further converted to json format using an arrow function. You can read about the arrow functions [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions).

Once we receive the json output, we are only interested in obtaining the translated text data and not the complete json object in itself (containing the 3 attributes discussed above). Since the __translated__ attribute is present within the __"contents"__ object, we refer to them as ` json.contents.translated `.

We now update the output div section to show the translated text value by replacing "translation in progress" to the message in minion language.

Funtranslation APIs are free to use, hence they have a limitation over the number of times this API can be called. Once it exceeds this limit, it would result in a failure with error. In order to handle this error message, we use the exception handler `.catch(errorHandler)`. By implementing the following logic, we would display an alert message to the user if the API fails to serve us with the correct result.

```javascript
function errorHandler(error) {
    console.log("error occured", error);
    alert("Something wrong with the server, try again later.");
}
```
At the end of this, we must be able to acquire the following result.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/xctgrvbb1ykreheyyvw3.png)

That brings us to the end of creating this app's logic. All that we are left with is to incorporated the styling which involves CSS. You can bring in all the creativity in designing this application by providing your own touch of design. You can also take a step further and create a similar app with a different translation language too!

You may refer to the app created by me --> [Let's go Bananas](https://supminn-neog-bananaspeak.netlify.app/). Give it a try, create your version of the same and share your experience and feedback on the comments section. 
I hope this article was helpful in providing some insights about JavaScript and server calls.

Peace!

We now have this article translated to Spanish. You can read it [here](https://www.ibidemgroup.com/edu/app-traduccion-minion/). Translation by [Chema Bescós](https://www.linkedin.com/in/josemariabescos/)