Discover the process of translating words within app.routing.module.ts in Angular

Having some trouble with my Angular routing module and ngx-translate languages. I'm trying to retrieve words from the languages in this module, but the code I've attempted isn't working:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AuthGuard } from '../../auth/auth.guard';
import { CategoryComponent } from './category/category.component';
import { SubCategoryComponent } from './category/sub-category/sub-category.component';

import { ColorsComponent } from './colors.component';
import { TypographyComponent } from './typography.component';

const routes: Routes = [
  {
    path: '',
    data: {
      title: "{{'NameEng' | translate}}"
    },
    children: [
      {
        path: '',
        redirectTo: 'colors'
      },
      {
        path: 'colors',
        component: ColorsComponent,
        data: {
          title: 'Colors'
        }
      },
      {
        path: 'typography',
        component: TypographyComponent,
        canActivate:[AuthGuard],
        data: {
          title: 'Typography'
        }
      },
      {
        path: 'category',
        component: CategoryComponent,
        canActivate:[AuthGuard],
        data: {
          title: 'Categories'
        }
      },
      {
        path: 'subcategory',
        component: SubCategoryComponent,
        canActivate:[AuthGuard],
        data: {
          title: 'Sub Categories'
        }
      }
    ]
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class ThemeRoutingModule {}

Having issues fetching the Title data from the translateService. Can anyone assist me with this problem? Thanks.

Answer №1

It appears that you are utilizing CoreUI.

While CoreUI doesn't natively support breadcrumb translation, you have the option to duplicate the breadcrumb component and customize it for translation purposes.

This response has been adapted from a solution provided here.

breadcrumb.component.html (Note that it will attempt to fetch the translated title; if not available, it will display the raw value used in the title key).

<ol class="breadcrumb">
<ng-container *ngFor="let breadcrumb of breadcrumbs | async, let last = last">
    <li class="breadcrumb-item"
        *ngIf="breadcrumb.label.title && (breadcrumb.url.slice(-1) == '/' || last)"
        [ngClass]="{active: last}">
        <a *ngIf="!last" [routerLink]="breadcrumb.url" >{{ tr[breadcrumb.label.title] != null ? tr[breadcrumb.label.title] : breadcrumb.label.title }}</a>
        <span *ngIf="last" [routerLink]="breadcrumb.url" >{{ tr[breadcrumb.label.title] != null ? tr[breadcrumb.label.title] : breadcrumb.label.title }}</span>
    </li>
</ng-container>

breadcrumb.component.ts

import {Component, ElementRef, Inject, Input, OnDestroy, OnInit, Renderer2} from '@angular/core';
import {DOCUMENT} from '@angular/common';
import {TranslationService} from '../../../services/translation.service';


import {BreadcrumbService} from './breadcrumb.service';

function Replace(el: any): any {
    const nativeElement: HTMLElement = el.nativeElement;
    const parentElement: HTMLElement = nativeElement.parentElement;

    // move all children out of the element
    while (nativeElement.firstChild) {
        parentElement.insertBefore(nativeElement.firstChild, nativeElement);
    }

    // remove the empty element(the host)
    parentElement.removeChild(nativeElement);
}

@Component({
    selector: 'app-custom-breadcrumb',
    templateUrl: './breadcrumb.component.html',
})
export class BreadcrumbComponent implements OnInit, OnDestroy {
    public tr; // translation service

    @Input() fixed: boolean;
    breadcrumbs;
    private readonly fixedClass = 'breadcrumb-fixed';

    constructor(
        @Inject(DOCUMENT) private document: any,
        private renderer: Renderer2,
        public service: BreadcrumbService,
        public el: ElementRef,
        private translationService: TranslationService,
    ) {
        this.tr = translationService.getTranslations();
    }

    ngOnInit(): void {
        Replace(this.el);
        this.isFixed(this.fixed);
        this.breadcrumbs = this.service.breadcrumbs;
    }

    ngOnDestroy(): void {
        this.renderer.removeClass(this.document.body, this.fixedClass);
    }

    isFixed(fixed: boolean = this.fixed): void {
        if (fixed) {
            this.renderer.addClass(this.document.body, this.fixedClass);
        }
    }
}

breadcrumb.service.ts (unchanged)

import { Injectable } from '@angular/core';
import { Router, ActivatedRoute, NavigationEnd } from '@angular/router';
import { BehaviorSubject, Observable } from 'rxjs';
import { filter } from 'rxjs/operators';

@Injectable({
    providedIn: 'root'
})
export class BreadcrumbService {

    breadcrumbs: Observable<Array<any>>;

    private breadcrumbSubject: BehaviorSubject<Array<any>>;

    constructor(private router: Router, private route: ActivatedRoute) {

        this.breadcrumbSubject = new BehaviorSubject<any[]>(new Array<any>());

        this.breadcrumbs = this.breadcrumbSubject.asObservable();

        this.router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe((event) => {
            const breadcrumbs = [];
            let currentRoute = this.route.root;
            let url = '';
            do {
                const childrenRoutes = currentRoute.children;
                currentRoute = null;
                childrenRoutes.forEach(route => {
                    if (route.outlet === 'primary') {
                        const routeSnapshot = route.snapshot;
                        url += '/' + routeSnapshot.url.map(segment => segment.path).join('/');
                        breadcrumbs.push({
                            label: route.snapshot.data,
                            url
                        });
                        currentRoute = route;
                    }
                });
            } while (currentRoute);

            this.breadcrumbSubject.next(Object.assign([], breadcrumbs));

            return breadcrumbs;
        });
    }
}

Ensure your Translation service is configured as follows: translation.service.ts

import {Injectable, LOCALE_ID, Inject} from '@angular/core';
import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http';

@Injectable({
    providedIn: 'root'
})


export class TranslationService {

    private trans_es;
    private trans_en;

    private localeId = '';
    private es = 'es';
    private en = 'en';

    public translatedLabels;

    headers: HttpHeaders = new HttpHeaders({
        'Content-Type': 'application/json'
    });

    constructor(@Inject(LOCALE_ID) private locale) {


        this.trans_es = {};
        this.trans_en = {};

        
        this.trans_es['typography'] = 'Tipografía';
        this.trans_en['typography'] = 'Typography';
        this.trans_es['colors'] = 'Colores';
        this.trans_en['colors'] = 'Colors';
       

        if (locale === 'en') {
            const s = JSON.stringify(this.trans_en);
            const c = JSON.parse(s);
            this.translatedLabels = c;
        } else {
            const s = JSON.stringify(this.trans_es);
            const c = JSON.parse(s);
            this.translatedLabels = c;
        }
    }

    public getTranslations() {
        return this.translatedLabels;
    }


}

In the HTML where the breadcrumbs are displayed:

<app-custom-breadcrumb>
        <li class="breadcrumb-menu d-md-down-none">
        </li>
</app-custom-breadcrumb>

You can then utilize it on every route like so:

const routes: Routes = [
  {
    path: '',
    component: ColorsComponent,
    data: {
      title: 'colors'
    }
  }
];

Answer №2

This helpful tool can be used for dependency management: https://www.npmjs.com/package/@biesbjerg/ngx-translate-extract-marker

To make use of this dependency, follow these steps:

➜ npm i @biesbjerg/ngx-translate-extract-marker --save

After installing the dependencies, import and integrate it as shown below:

import { marker as _ } from "@biesbjerg/ngx-translate-extract-marker";

import { ColorsComponent } from './colors.component';
import { TypographyComponent } from './typography.component';

const routes: Routes = [
  {
    path: '',
    data: {
      title: _("NameEng")
    },
    children: [
      {
        path: '',
        redirectTo: 'colors'
      },
      {
        path: 'colors',
        component: ColorsComponent,
        data: {
          title: 'Colors'
        }
      },
      {
        path: 'typography',
        component: TypographyComponent,
        canActivate:[AuthGuard],
        data: {
          title: 'Typography'
        }
      },
      {
        path: 'category',
        component: CategoryComponent,
        canActivate:[AuthGuard],
        data: {
          title: 'Categories'
        }
      },
      {
        path: 'subcategory',
        component: SubCategoryComponent,
        canActivate:[AuthGuard],
        data: {
          title: 'Sub Categories'
        }
      }
    ]
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class ThemeRoutingModule {}

Answer №3

Static route files do not evaluate Angular template directives or expression language. To work around this, you can translate the keys when accessing the data from the routes, possibly within a header element.

To achieve this with `ngx-translate`, you can utilize the `TranslateService` methods such as `get` or `instant`, or assign translation keys to a component field and use the `translate` pipe in the component template as usual.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Which one should you begin with: AngularJS or Angular 2?

Interested in learning Angular and curious about the differences between Angular, AngularJS, and Angular 2. Should I focus on educating myself on Angular or go straight to Angular 2, considering it's now in beta version? Is there a significant differ ...

Messages are not being emitted from the socket

I've been encountering an issue with message transmission from client to server while using React and ExpressJS. When I trigger the sendMessage function on the client side, my intention is to send a message to the server. However, for some reason, the ...

What's the deal with Angular query parameters and parentheses?

My Angular application has a routing structure that includes a query parameter. Here is an example: const routes: Routes = [{ path: '', component: DefaultComponent }, { path: ':uname', component: ProductDisplayComponent }]; Whe ...

Tips for showing the upcoming week in an angular application

Could someone please assist me with displaying the dates for the next 7 days using TypeScript? I am familiar with obtaining the date for the 7th day ahead, but I am unsure on how to generate a list of the 7 consecutive days. ...

How can you utilize both defineProps with TypeScript and set default values in Vue 3 setup? (Typescript)

Is there a way to use TypeScript types and default values in the "defineProps" function? I'm having difficulty getting it to work. Code snippet: const props = defineProps<{ type?: string color?: 'color-primary' | 'color-danger&a ...

Tips for asynchronously loading moment.js timezone data in Angular

I have recently added the following package: npm install moment-timezone --save Within my angular component, I am utilizing it in this manner: import * as moment from 'moment-timezone'; moment().tz('America/New York'); However, I su ...

leveraging third party plugins to implement callbacks in TypeScript

When working with ajax calls in typical javascript, I have been using a specific pattern: myFunction() { var self = this; $.ajax({ // other options like url and stuff success: function () { self.someParsingFunction } } } In addition t ...

Troubleshooting the error message "Encountering issues with Module build failed (from ./node_modules/postcss-loader/src/index.js)"

Running ng serve results in compilation failure after the chunks are generated. The same codebase is functioning on a co-worker's computer with identical versions as listed below: Node version: 10.16.3 NPM version: 6.9.0 @angular/cli: 7.3.9 Tried ...

The Typescript intellisense feature in VS Code seems to be malfunctioning

While setting up typings for my Node server, the intellisense suddenly stopped working. I checked my tsconfig.json file: { "version": "0.1.0", "command": "tsc", "isShellCommand": true, "args": ["-p", "."], "showOutput": "silent", " ...

Struggling with getting render props to work in Next.js version 13

Looking to develop a custom component for Contentful's next 13 live preview feature in the app directory, I thought of creating a client component that can accept a data prop and ensure type safety by allowing a generic type to be passed down. Here is ...

Ways to import a library in JavaScript/TypeScript on a web browser?

I'm currently working on a project that involves a TypeScript file and an HTML page. Right now, I am loading the necessary libraries for the TypeScript file in the HTML Page using script tags like <script src="https://unpkg.com/<a href="/cd ...

Utilizing a JSDoc comment from an external interface attribute

Currently, I am in the process of developing a React application. It is common to want the props of a child component to be directly connected to the state of a parent component. To achieve this, I have detailed the following instructions in the interface ...

Utilizing SCSS variables

Currently, I am in the process of developing an Angular 4 application using angular-cli and have encountered a minor issue. I am attempting to create a component that has the ability to dynamically load styling. The ComponentX component needs to utilize a ...

What is the best way to convert dates in Angular's DatePipe using moment.js?

My current package versions are as follows: "@angular/cdk": "^11.2.13", "@ngx-translate/core": "^13.0.0", "@angular/material-moment-adapter": "^12.2.9", "moment": "^2.29.1", &q ...

`The error "mockResolvedValue is not recognized as a function when using partial mocks in Jest with Typescript

Currently, I am attempting to partially mock a module and customize the return value for the mocked method in specific tests. An error is being thrown by Jest: The error message states: "mockedEDSM.getSystemValue.mockResolvedValue is not a function TypeEr ...

What are the best ways to utilize .svg images for native script splash screens, backgrounds, icons, and buttons?

I am interested in replacing the .png files I previously used for my native script android app with .svg files. My goal is to utilize svg images for splash screens, backgrounds, icons, and buttons. Thank you! ...

What is the procedure for entering the output generated by genMockFromModule when creating a custom mock in Jest?

Looking at my orders directory structure, I have a function in the orders/helpers file that I want to test using a manual Jest mock. orders __mocks__ helpers.ts __tests__ orders.ts helpers.ts orders.ts The orders/helpers.ts file contains ...

Integrating Video.js with the latest version of Angular, Angular

Looking to integrate Video.js into my Angular 6 project and retrieve the current play time and video duration. I came across the @types/video.js library but unsure of the correct way to utilize it. Any advice on how to properly implement it? ...

Different Styles of Typescript Function Declarations

I recently started experimenting with Typescript and I'm a bit confused about the differences between these two method declarations: onSave() { /*method body*/ } public onSave = () => { /*method body*/ } Additionally, could someone point me in th ...

Ways to retrieve the quantity of a particular value within an object using TypeScript

I'm inquiring about how to retrieve the number of a specific value within an object using TypeScript. Here is the structure of the object: obj : TestObject = { name: "test", street: "test" subobj1: { status: warning, time: ...