Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/dreancaste/TriviaPP/llms.txt

Use this file to discover all available pages before exploring further.

TranslationService bridges SWAPI’s English-language data and TriviaPP’s Spanish-language UI. Because SWAPI returns values such as planet climates ("arid", "temperate, tropical") and film descriptions in English, this service transparently converts them to Spanish before they appear in question text or answer options. It uses the free MyMemory REST API for translation, applies automatic text chunking to stay within the API’s 450-character query limit, and capitalises the result for consistent display.

Constructor / Dependencies

DependencyTokenRole
HttpClient@angular/common/httpIssues GET requests to the MyMemory API
@Injectable({ providedIn: 'root' })
export class TranslationService {
  private readonly maxQueryLength = 450;
  constructor(private http: HttpClient) {}
}

Public Methods

translate()

The primary translation entry point. Translates a string from English to Spanish, capitalises each comma-separated segment of the result, and falls back to the original (capitalised) input if the API call fails.
async translate(text: string): Promise<string>
text
string
required
The English text to translate. Typical inputs are SWAPI climate strings such as "arid", "temperate, tropical", or "frozen".
Post-processing applied to the translated result:
  1. replace(/\bde\b/gi, 'de') — normalises stray de prepositions that MyMemory sometimes leaves with incorrect casing.
  2. capitalize() — splits on commas, trims each segment, uppercases the first character, and lowercases the rest (e.g. "árido, TEMPLADO""Árido, Templado").
On any error (network failure, API error, unexpected response shape), the method catches the exception and returns the capitalised original input rather than throwing.

translateRaw()

The lower-level translation method called internally by translate(). Handles the chunking strategy for long texts and dispatches individual API calls.
async translateRaw(text: string): Promise<string>
text
string
required
Raw English text to translate. May be of any length — chunking is applied automatically.
Chunking behaviour:
  • If text.length <= 450: calls requestTranslation(text) directly and returns the result.
  • If text.length > 450: calls splitForApi(text) to break the text into sentence-level chunks, dispatches all chunks to requestTranslation() concurrently via Promise.all(), and joins the translated segments with a space.
Returns the original text on error rather than throwing.

Internal Methods (Implementation Detail)

These private methods are not part of the public API but are described here for contributors and advanced integrators.

requestTranslation(text) (private)

Issues the actual HTTP GET to MyMemory and extracts the translated string from the response. Endpoint:
GET https://api.mymemory.translated.net/get?q={encodeURIComponent(text)}&langpair=en|es
Returns the original text if the response is absent, if the API returns "QUERY LENGTH LIMIT EXCEEDED", or if any error occurs.

splitForApi(text) (private)

Splits text at sentence boundaries (., !, ?) to produce chunks each no longer than 450 characters. Algorithm:
  1. Normalises whitespace.
  2. Splits on sentence-terminal punctuation using a regex.
  3. Accumulates sentences into the current chunk; when adding the next sentence would exceed 450 characters, flushes the current chunk and starts a new one.
  4. If a single sentence is itself longer than 450 characters, delegates to splitLongText().

splitLongText(text) (private)

Splits an individual oversized string on word boundaries, accumulating words until the next word would exceed the 450-character limit, then flushing to a new chunk.

API Reference

ParameterValue
Endpointhttps://api.mymemory.translated.net/get
Query param qURL-encoded source text
Query param langpairen|es (English → Spanish)
Max q length450 characters
Response fieldresponseData.translatedText
MyMemory’s free tier allows approximately 5,000 words per day per IP address (anonymous usage). In a typical TriviaPP session, climate strings are short (under 50 characters each), so the limit is unlikely to be hit during normal play. If the daily limit is reached, requestTranslation() returns the original English text, and the question will display untranslated values rather than failing.

Usage in Context

TriviaService calls translate() directly when building planet climate questions:
// Inside TriviaService.generatePlanetQuestion()
const translatedCorrectAnswer = await this.translationService.translate(planet.climate);

const translatedWrongAnswers = await Promise.all(
  wrongAnswers.map(answer => this.translationService.translate(answer))
);
Climate strings such as "arid""Árido" and "temperate, tropical""Templado, Tropical" are produced this way before being assembled into the answer options array.

Usage Example

import { TranslationService } from './services/translation.service';

@Injectable({ providedIn: 'root' })
export class PlanetDetailService {
  constructor(private translation: TranslationService) {}

  async translatePlanetDetails(planet: any) {
    const [climate, terrain] = await Promise.all([
      this.translation.translate(planet.climate),
      this.translation.translate(planet.terrain),
    ]);

    return { ...planet, climate, terrain };
  }

  // For long-form text (e.g. film opening crawls), translateRaw
  // handles chunking automatically without post-processing capitalisation
  async translateOpeningCrawl(crawl: string): Promise<string> {
    return this.translation.translateRaw(crawl);
  }
}
Do not call translateRaw() directly in UI code for short strings that will be displayed to players. Use translate() instead — it applies the capitalisation and de normalisation that makes translated climate values render consistently in answer options.

Build docs developers (and LLMs) love