Create A Simple Translator App in Angular 16 with Azure Cognitive Service

Introduction 

Azure Cognitive Services are a collection of cloud-based AI (Artificial Intelligence) and ML services provided by Microsoft Azure. It offers pre-built APIs and tools for various domains, such as vision, speech, language, knowledge, and search. These services enable developers to incorporate intelligent capabilities into their applications without extensive AI ability. Azure Cognitive Services includes features like image recognition, speech recognition and synthesis, language understanding, sentiment analysis, and more, making it easier to build intelligent applications across different industries. 

Language Services in Azure Cognitive Services 

Language Services in Azure Cognitive Services supply a range of APIs and tools for natural language processing (NLP) tasks. These services enable developers to incorporate language understanding and analysis capabilities into their applications. Key language services include Text Analytics for sentiment analysis, key phrase extraction, and named entity recognition. Language Understanding (LUIS) for creating custom language models and intent recognition. Translator Text for automatic machine translation between languages and Speech to Text and Text to Speech for converting speech to written text and generating spoken output. These language services empower developers to process and interpret text, enable multilingual support, and enhance the language capabilities of their applications. 

Translator Service in Language Services

Azure Cognitive Services includes a service called Translator Text, which supplies automatic machine translation capabilities. The Translator Text API allows developers to integrate language translation functionality into their applications, enabling the translation of text between different languages. 

Here are some key features and capabilities of Translator service in Azure Cognitive Services: 

Language Translation:  

The Translator Text API supports translation between a wide range of languages, including commonly spoken languages and less widely spoken ones. It supplies high-quality machine translation powered by advanced neural machine translation models. 

Text Translation:  

With the Translator Text API, you can translate text strings, paragraphs, or entire documents from one language to another. It supports both single-string translations and batch translations for larger volumes of text. 

Language Detection:  

The API includes language detection capabilities, which can automatically find the language of a given text. This is useful when the source language is unknown or when you want to build language-agnostic applications. 

Transliteration:  

Translator Text also supports transliteration, which involves converting text from one script or alphabet to another while preserving the pronunciation. This is particularly useful for languages with different writing systems, enabling you to display text in a familiar script. 

Language Support:  

Translator Text supports a wide range of languages, including major languages like English, Hindi, Spanish, French, Chinese, Arabic, and many others. The number of supported languages continues to expand over time. 

Customization:  

You can improve translation quality by customizing the Translator Text models with your own translation data. This allows you to fine-tune the translation engine to better suit specific domains, jargon, or industry-specific terminology. 

By using the Translator Text API, developers can incorporate language translation capabilities into their applications, making it easier to supply multilingual support, localize content, and enable communication across different languages. This is particularly valuable for global applications, websites, chatbots, and other solutions that require language translation as a core functionality. 

In this post, we will see how to create a simple Translator application in Angular 16 with the help of Translator service in Azure Cognitive Services.  

Create Translator service in Azure Portal

Choose Translator blade under Language tab in Azure Cognitive Services. 

We can choose pricing tiers as Free for testing purpose. Please note that under one subscription, only one free tier is available.  

It will take a few moments to complete the resource deployment. 

We can choose Keys and Endpoint tab to get keys and store them in any safe place. We will use this key in our Web API application later. Azure also provides the option to regenerate the keys if needed.  

We can create a Web API with .NET 6.0 for our Translator application. 

Create Web API in Visual Studio 2022 with .NET 6.0 SDK 

.NET 7.0 is already stable but not in long term support by Microsoft. Hence, I am choosing .NET 6.0 SDK which is under LTS.  

After creating the project, we can create an interface ITranslator. 

ITranslator.cs 

namespace Translator.NET6;
public interface ITranslator
{
    Task<string> Translate(string textToTranslate, string langCode);
}

We must install Newtonsoft.Json NuGet library in the project. 

Create a service TranslatorService and implement from ITranslator interface. 

TranslatorService.cs 

using Newtonsoft.Json;
using System.Text;

namespace Translator.NET6;
public class TranslatorService : ITranslator
{
    private static readonly string key = "ddb567cbfbee483ca5641d0eb7431812";
    private static readonly string endpoint = "https://api.cognitive.microsofttranslator.com";
    private static readonly string location = "eastus";
    public async Task<string> Translate(string textToTranslate, string langCode)
    {

        string route = "/translate?api-version=3.0&from=en&to=" + langCode;
        object[] body = new object[] { new { Text = textToTranslate } };
        var requestBody = JsonConvert.SerializeObject(body);

        using (var client = new HttpClient())
        using (var request = new HttpRequestMessage())
        {
            // Build the request.
            request.Method = HttpMethod.Post;
            request.RequestUri = new Uri(endpoint + route);
            request.Content = new StringContent(requestBody, Encoding.UTF8, "application/json");
            request.Headers.Add("Ocp-Apim-Subscription-Key", key);
            // location required if you're using a multi-service or regional (not global) resource.
            request.Headers.Add("Ocp-Apim-Subscription-Region", location);

            // Send the request and get response.
            HttpResponseMessage response = await client.SendAsync(request).ConfigureAwait(false);
            // Read response as a string.
            string result = await response.Content.ReadAsStringAsync();
            return result;
        }
    }
}

Please note that the key provided in this code varies from your translator key. Please get the correct code from Azure portal.  

We must add the code below in Program.cs file for service dependency injection and adding CORS. 

Program.cs 

using Translator.NET6;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddSingleton<ITranslator, TranslatorService>();
var MyAllowedOrigins = "_myAllowedOrigins";

builder.Services.AddCors(options =>
{
    options.AddPolicy(MyAllowedOrigins,
                          builder =>
                          {
                              builder.WithOrigins("http://localhost:4200")
                                                  .AllowAnyHeader()
                                                  .AllowAnyMethod();
                          });
});
var app = builder.Build();

app.UseCors(MyAllowedOrigins);

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseAuthorization();

app.MapControllers();

app.Run();

Create Translator controller inside the Controllers folder and add the code below. 

TranslatorController.cs 

using Microsoft.AspNetCore.Mvc;

namespace Translator.NET6.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class TranslatorController : ControllerBase
    {
        private readonly ITranslator _translator;
        public TranslatorController(ITranslator translator)
        {
            _translator = translator;
        }

        [HttpGet("{value}/{language}")]
        public async Task<IActionResult> Get(string value, string language)
        {
            return Ok(await _translator.Translate(value, language));
        }
    }
}

We have completed all code for Web API. We can run the code and test translation in Swagger. 

Translate method has two parameters value and language. We must give the correct language code for each language. 

Please refer to the site below for all language codes.  

https://www.loc.gov/standards/iso639-2/php/code_list.php

Create Angular 16 project using Angular CLI 

We can use the command below to create the new Angular 16 project. 

ng new TranslatorAngular16 

It will take a few moments to create the Angular project.

We can install bootstrap latest version in our project for styling. 

npm install bootstrap 

We can add below code in styles.css file. So that bootstrap will be available across applications without further reference. 

styles.css 

@import "~bootstrap/dist/css/bootstrap.css";

We can import FormModule and HttpClientModule in app.module.  

app.module.ts 

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,
    HttpClientModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Modify the app component file with the code below. 

app.component.ts 

import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'TranslatorAngular16';

  mySelect!: string;
  languages: language[] = [];
  url!: string;
  inputValue!: string;
  outputValue!: string;

  constructor(private http: HttpClient) {
    this.url = 'http://localhost:5000/api/translator';
  }

  ngOnInit(): void {

    this.languages.push({ value: 'Hindi', code: 'hi' }, { value: 'Tamil', code: 'ta' }, { value: 'Malayalam', code: 'ml' }, { value: 'Telugu', code: 'te' }, { value: 'Kannada', code: 'kn' });
  }

  translate() {
    console.log(this.mySelect)
    if (!this.mySelect) {
      alert('Please select any language');
      return;
    }
    if (!this.inputValue) {
      alert('Please enter some values to Translate');
      return;
    }
    this.http.get<any>(this.url + '/' + this.inputValue + '/' + this.mySelect)
      .subscribe({
        next: (result) => {
          this.outputValue = result[0].translations[0].text;
        },
        error: (err) => {
          alert('Some error occured! Please try later.')
          console.error(err);
        },
        complete: () => console.info('Request completed')
      });
  }
}

export class language {
  value!: string;
  code!: string;
}

Please note that we have added 5 Indian languages with corresponding translation code. 

Modify app component html with the code below. 

app.component.html 

<!-- Toolbar -->
<div class="toolbar" role="banner">
  <img width="40" alt="Angular Logo"
    src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==" />
  <span>Simple Translator App in Angular 16 with Azure Cognitive Services</span>
  <div class="spacer"></div>
  <a aria-label="Angular on twitter" target="_blank" rel="noopener" href="https://twitter.com/sarathlalsasee1" title="Twitter">
    <svg id="twitter-logo" height="24" data-name="Logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400">
      <rect width="400" height="400" fill="none" />
      <path
        d="M153.62,301.59c94.34,0,145.94-78.16,145.94-145.94,0-2.22,0-4.43-.15-6.63A104.36,104.36,0,0,0,325,122.47a102.38,102.38,0,0,1-29.46,8.07,51.47,51.47,0,0,0,22.55-28.37,102.79,102.79,0,0,1-32.57,12.45,51.34,51.34,0,0,0-87.41,46.78A145.62,145.62,0,0,1,92.4,107.81a51.33,51.33,0,0,0,15.88,68.47A50.91,50.91,0,0,1,85,169.86c0,.21,0,.43,0,.65a51.31,51.31,0,0,0,41.15,50.28,51.21,51.21,0,0,1-23.16.88,51.35,51.35,0,0,0,47.92,35.62,102.92,102.92,0,0,1-63.7,22A104.41,104.41,0,0,1,75,278.55a145.21,145.21,0,0,0,78.62,23"
        fill="#fff" />
    </svg>
  </a>
  <a aria-label="Angular on YouTube" target="_blank" rel="noopener" href="https://www.youtube.com/@sarathlalsaseendran" title="YouTube">
    <svg id="youtube-logo" height="24" width="24" data-name="Logo" xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 24 24" fill="#fff">
      <path d="M0 0h24v24H0V0z" fill="none" />
      <path
        d="M21.58 7.19c-.23-.86-.91-1.54-1.77-1.77C18.25 5 12 5 12 5s-6.25 0-7.81.42c-.86.23-1.54.91-1.77 1.77C2 8.75 2 12 2 12s0 3.25.42 4.81c.23.86.91 1.54 1.77 1.77C5.75 19 12 19 12 19s6.25 0 7.81-.42c.86-.23 1.54-.91 1.77-1.77C22 15.25 22 12 22 12s0-3.25-.42-4.81zM10 15V9l5.2 3-5.2 3z" />
    </svg>
  </a>
</div>

<div class="content" role="main">
  <div class="col-sm-12">
    <div class="row background">
      Choose a Language:
    </div>
    <div class="row background">
      <select name="my-select" [(ngModel)]="mySelect">
        <option [value]="item.code" *ngFor="let item of languages">
          {{item.value}}
        </option>
      </select>
    </div>

    

  </div>

  <div class="container">
    <div class="row">
      <div class="col-sm-6 background">
        <label for="otext">Original Text:</label>
      </div>
      <div class="col-sm-6 background">
        <label for="otext">Translated Text:</label>
      </div>
    </div>
    <div class="row" style="height:50vh;">
      <div class="col-sm-6 background" style="height:50vh;">

        <textarea id="otext" name="Orginal Text" rows="10" cols="50" [(ngModel)]="inputValue">
          </textarea>
      </div>
      <div class="col-sm-6 background" style="height:50vh;">
        <textarea id="ttext" name="Translated Text" rows="10" cols="50" [(ngModel)]="outputValue">
        </textarea>
      </div>
    </div>
    <div class="row">
      <button type="button" class="btn btn-success"(click)="translate()">Translate</button>
    </div>
  </div>

</div>
<router-outlet></router-outlet>

Modify the app component style with the code below. 

app.component.css

:host {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
    font-size: 14px;
    color: #333;
    box-sizing: border-box;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1,
h2,
h3,
h4,
h5,
h6 {
    margin: 8px 0;
}

p {
    margin: 0;
}

.spacer {
    flex: 1;
}

.toolbar {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 60px;
    display: flex;
    align-items: center;
    background-color: #1976d2;
    color: white;
    font-weight: 600;
}

.toolbar img {
    margin: 0 16px;
}

.toolbar #twitter-logo {
    height: 40px;
    margin: 0 8px;
}

.toolbar #youtube-logo {
    height: 40px;
    margin: 0 16px;
}

.toolbar #twitter-logo:hover,
.toolbar #youtube-logo:hover {
    opacity: 0.8;
}

.content {
    display: flex;
    margin: 82px auto 32px;
    padding: 0 16px;
    max-width: 960px;
    flex-direction: column;
    align-items: center;
}

svg.material-icons {
    height: 24px;
    width: auto;
}

svg.material-icons:not(:last-child) {
    margin-right: 8px;
}

.card svg.material-icons path {
    fill: #888;
}

.card-container {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    margin-top: 16px;
}

.card {
    all: unset;
    border-radius: 4px;
    border: 1px solid #eee;
    background-color: #fafafa;
    height: 40px;
    width: 200px;
    margin: 0 8px 16px;
    padding: 16px;
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
    transition: all 0.2s ease-in-out;
    line-height: 24px;
}

.card-container .card:not(:last-child) {
    margin-right: 0;
}

.card.card-small {
    height: 16px;
    width: 168px;
}

.card-container .card:not(.highlight-card) {
    cursor: pointer;
}

.card-container .card:not(.highlight-card):hover {
    transform: translateY(-3px);
    box-shadow: 0 4px 17px rgba(0, 0, 0, 0.35);
}

.card-container .card:not(.highlight-card):hover .material-icons path {
    fill: rgb(105, 103, 103);
}

.card.highlight-card {
    background-color: #1976d2;
    color: white;
    font-weight: 600;
    border: none;
    width: auto;
    min-width: 30%;
    position: relative;
}

.card.card.highlight-card span {
    margin-left: 60px;
}

svg#rocket {
    width: 80px;
    position: absolute;
    left: -10px;
    top: -24px;
}

svg#rocket-smoke {
    height: calc(100vh - 95px);
    position: absolute;
    top: 10px;
    right: 180px;
    z-index: -10;
}

a,
a:visited,
a:hover {
    color: #1976d2;
    text-decoration: none;
}

a:hover {
    color: #125699;
}

.terminal {
    position: relative;
    width: 80%;
    max-width: 600px;
    border-radius: 6px;
    padding-top: 45px;
    margin-top: 8px;
    overflow: hidden;
    background-color: rgb(15, 15, 16);
}

.terminal::before {
    content: "\2022 \2022 \2022";
    position: absolute;
    top: 0;
    left: 0;
    height: 4px;
    background: rgb(58, 58, 58);
    color: #c2c3c4;
    width: 100%;
    font-size: 2rem;
    line-height: 0;
    padding: 14px 0;
    text-indent: 4px;
}

.terminal pre {
    font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
    color: white;
    padding: 0 1rem 1rem;
    margin: 0;
}

.circle-link {
    height: 40px;
    width: 40px;
    border-radius: 40px;
    margin: 8px;
    background-color: white;
    border: 1px solid #eeeeee;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
    transition: 1s ease-out;
}

.circle-link:hover {
    transform: translateY(-0.25rem);
    box-shadow: 0px 3px 15px rgba(0, 0, 0, 0.2);
}

footer {
    margin-top: 8px;
    display: flex;
    align-items: center;
    line-height: 20px;
}

footer a {
    display: flex;
    align-items: center;
}

.github-star-badge {
    color: #24292e;
    display: flex;
    align-items: center;
    font-size: 12px;
    padding: 3px 10px;
    border: 1px solid rgba(27, 31, 35, .2);
    border-radius: 3px;
    background-image: linear-gradient(-180deg, #fafbfc, #eff3f6 90%);
    margin-left: 4px;
    font-weight: 600;
}

.github-star-badge:hover {
    background-image: linear-gradient(-180deg, #f0f3f6, #e6ebf1 90%);
    border-color: rgba(27, 31, 35, .35);
    background-position: -.5em;
}

.github-star-badge .material-icons {
    height: 16px;
    width: 16px;
    margin-right: 4px;
}

svg#clouds {
    position: fixed;
    bottom: -160px;
    left: -230px;
    z-index: -10;
    width: 1920px;
}


.background{
  background-color:#1976d2;
  color:#e6ebf1;
  font-size: large;
  padding: 10px;
}


/* Responsive Styles */
@media screen and (max-width: 767px) {

    .card-container>*:not(.circle-link),
    .terminal {
        width: 100%;
    }

    .card:not(.highlight-card) {
        height: 16px;
        margin: 8px 0;
    }

    .card.highlight-card span {
        margin-left: 72px;
    }

    svg#rocket-smoke {
        right: 120px;
        transform: rotate(-5deg);
    }
}

@media screen and (max-width: 575px) {
    svg#rocket-smoke {
        display: none;
        visibility: hidden;
    }
}

We have completed the entire coding for Angular project.  

We can run both Web API project and Angular project now. 

We can choose any language from the dropdown and click Translate button. 

I have chosen Hindi language. 

We can choose some other language and click Translate button again. 

I have chosen Malayalam this time. 

You can add more languages which are supported by Azure and extend our application if needed. 

Conclusion 

In this post, we have seen how to create a simple Translator app in Angular 16 using Azure Translator service in Azure Cognitive service. We have created a Translator service in Azure portal. We have created a Web API application with .NET 6.0 SDK and added a Translator service to the application. After that we created a controller and used Translator service inside the controller.