We have a custom directive in our project which we use when we want trim the long text in some UI elements. In one case it fails to work. There are no errors, no warnings, it's just no there. Checking the code in the DevTools shows no signs of this directive triggering (no HTML changes, no CSS added). The directive looks like this:
ngAfterViewInit() {
let text = <string>this.elt.nativeElement.innerHTML.trim();
if (!text || text !== (<HTMLElement>this.elt.nativeElement).innerText) {
return;
}
const limit = this.value || DEFAULT_VISIBLE_ENDING_LENGTH; // default length = 4
if (text.length > limit && this.elt.nativeElement.scrollWidth > this.elt.nativeElement.clientWidth) {
const startText = text.substr(0, text.length - limit);
const endText = text.substr(-limit);
this.renderer.setProperty(
this.elt.nativeElement,
'innerHTML',
`<div class="part1"><span>${startText}</span></div><div class="part2"><span><span>${endText}</span></span></div>`
);
}
}
It fails to work when the text to display & trim is obtained from observable (store selector). It doesn't matter if I use Observable + async pipe or if I map the value to the component property in selector subscribe.
@Component({
...
changeDetection: ChangeDetectionStrategy.OnPush,
})
this.sampleInProgress$: Observable<string>;
this.sampleInProgress: string;
...
this.sampleInProgress$ = this.store.select(fromAutomation.getInfoPanelData).pipe(
map(({ sample, experiment }) => {
this.sampleInProgress = sample?.sampleName; // does not work either
this.experimentInProgress = experiment?.parameterSet;
return sample?.sampleName;
}),
);
And the HTML:
<span class="label" gs-ellipsis>{{ sampleInProgress$ | async }}</span>
<!-- In this case, subscribe is done in the component -->
<span class="label" gs-ellipsis>{{ sampleInProgress }}</span>
Sorry for the bit messy code, I just didn't wanted to post almost the same code twice. I'm either subscribing explicitly or assigning the observable using async with it. Not doing both at the same time. The other place in the code where we use this ellipsis (and where it works) also uses OnPush Detection strategy the but that the value is provided by @Input.
I have a feeling that it has something to do with the ngAfterViewInit() in the directive itself, but I'm not sure. Directives are not my strongest field.
Any idea what can be the cause and how to fix it?