Search code examples
angularprimengstring-interpolationngx-translate

syntax of ngx-translate string used in a title attribute dynamically with a parameter from an provided array


I am trying to find the correct syntax for this to work:

<th *ngFor=" let col of columns" [class]="col.class || ''" pResizableColumn
[pSortableColumn]="col.field" pReorderableColumn
title="{{'sort.by.value'|translate:({value:col?.header}) }}">               
{{ col.header|translate }}
</th>

The columns are defined as:

export const defaultColumns = [
    {
        field: 'colour',
        type: 'string',
        header: 'Colour',
        filterMatchMode: 'contains'
    },
    {
        field: 'sample_template_id',
        type: 'number',
        header: 'Sample Type',
        filterMatchMode: 'equals',
    },
    {
        field: 'name',
        type: 'string',
        header: 'Name',
        filterMatchMode: 'contains'
    }
]

Part of my en-US.json translation file looks like this (as do the other languages):

"Colour": "Colour",
"Name": "Name",
"sort": {
        "by": {
            "a-z": "Sort: A-Z",
            "alerts": "Sort: ALERTS",
            "last-scanned": "Sort by last scanned",
            "type": "Sort: TYPE",
            "value": "Sort By {{value}}",
            "z-a": "Sort: Z-A"
        },
        "title": "Sort"
    },
"Sample Type": "Sample Type",

The part in question is the title attribute:

What I tried:

  1. title="{{'sort.by.value'|translate:({value:col?.header}) }}"

Result: Using interpolation in this title attribute throws an NG5002 error: error NG5002: Parser Error: Unexpected token {, expected identifier, keyword, or string at column 2 in [{{'sort.by.value'|translate:({value:col?.header}) }}]

  1. title="{{'sort.by.value'|translate:{value:col?.header} }}" (removing the () parentheses)

Result: Using interpolation in this title attribute throws an NG5002 error: error NG5002: Parser Error: Unexpected token {, expected identifier, keyword, or string at column 2 in [{{'sort.by.value'|translate:({value:col?.header}) }}]

  1. title="'sort.by.value'|translate:{value:col?.header}" (removing the interpolation)

Result: no error thrown, but also doesn't replace the string. Shows 'sort.by.value'|translate:{value:col?.header} in the HTML

  1. title="'sort.by.value'|translate:({value:col?.header})" (removing the interpolation but keeping the () parentheses)

Result: no error thrown, but also doesn't replace the string. Shows 'sort.by.value'|translate:({value:col?.header}) in the HTML

  1. title="'sort.by.value'|translate:{value:'Name'}" (removing parentheses, and replacing the dynamic col.header property with the string that is used)

Result: no error thrown, but also doesn't replace the string. Shows 'sort.by.value'|translate:({value:col?.header}) in the HTML

  1. title="{{'sort.by.value'|translate:{value:'Name'} }}" (adding the string interpolation again, replacing the dynamic col.header property with the string that is used)

Result: Shows the correct string (Sort by Name) in the HTML, but is not dynamic.

What did I miss? None of the other questions and proposed answers worked unfortunately..

I should mention it's still Angular 11 but will be updated soon, and this project uses primeng v11.1 and ngx-translate v13.0


Solution

  • To answer my own question after trying for half of the last day:

    this is the solution that I finally settled upon:

    title="{{'sort.by.value'|translate}} {{col?.header | translate}}"
    

    My problem was, I needed the col?.header translated as well and that just seemed to cumbersome to do with some translate parameters.

    I just had to pay attention, to make sure the title attribute is not [title] otherwise this also worked, as weird as it looks:

    [title]="(('sort.by.value'|translate) + ' ' + (col?.header | translate))"