0

I have an anchor tag in the web page whose href value depends on a service whose properties are not under control of this component. The service details are populated asynchronously.

To get the service details and create the href value, I thought of two approaches. My question is - Which is better in terms of performance ? What should be the better option ?

Using function as href atribute

This causes the function to be invoked continuously.

// Inside component.html
<div>
    <a [href]="getDetailsLink()"></a>
</div>

// Inside component.ts
@Component({ selector: 'user', template: `...` })
class UserComponent implements DoCheck {

    public detailsLink: string;

    constructor(
        private userService: UserService
    ) {

    }

    public getDetailsLink(): string {
        // Based on the below property
        const checkSomeProperty = this.userService.checkSomeProperty;

        // Construct details link
        this.detailsLink = `https://www.something.com/users/${this.userService.checkSomeProperty.someValue}`;
    }
}

Using ngDoCheck

// Inside component.html
<div>
    <a [href]="detailsLink"></a>
</div>

// Inside component.ts
@Component({ selector: 'user', template: `...` })
class UserComponent implements DoCheck {

    public detailsLink: string;

    constructor(
        private userService: UserService
    ) {

    }

    ngDoCheck() {
        if (this.userService.checkSomeProperty) {

            // Check changes for the property
            // Perform required action
            // Construct details link
            this.detailsLink = `https://www.something.com/users/${this.userService.checkSomeProperty.someValue}`;
        }
    }
}

Thank you for reading it till here. Any guidance is appreciated

Ravi Sankar Rao
  • 1,050
  • 11
  • 26

2 Answers2

1

You have some business logic to generate that url and services is the place for business logic. Solution one is the way to go here.

That being said, based on the fact that the https://www.something.com/users/ part of the link is static or not I would also think about using a pipe for building such a url, to take advantage of memoization.

You would end up having something like:

<a [href]="someUser | buildLink"></a>
  • If i use pipes, I guess I would still have the issue of unavailability of data in this.userService.checkSomeProperty ? – Ravi Sankar Rao Nov 26 '19 at 20:40
  • Moreover it looks like pipes might have additional performance overhead than ngDoCheck for simple manual checkings https://indepth.dev/the-difference-between-ngdocheck-and-asyncpipe-in-onpush-components/ – Ravi Sankar Rao Nov 26 '19 at 20:58
1

My opinion is that the first approach should definitely be avoided.

If a function is used this way, it will be invoked on every change detection cycle which can affect performance(sometimes, in a visible way).

ngDoCheck will also be called on each change detection cycle, so I would refrain myself from adding any serious work here.

One approach is the one proposed by Massimiliano: use a pipe so you can leverage the power of memoization. Here is a great talk which enhances the benefits of using pipes.

However, I think that for such cases, a pipe is not needed.

If you say that the value depends on a value provided by a service asynchronously, you can wrap this logic into Subjects and Observers.

user.service.ts

export class UserService {
    private linkChangedSubj = new Subject();

    get linkChanged$ () {
        return this.linkChangedSubj.asObservable();
    }


    changeLink (newLink) {
        /* ... */

        this.linkChangedSubj.next(newLink);
    }
}

user.component.ts

export class UserComponent {

    constructor (private userService: UserService) { }

    ngOnInit () {
        this.userService.linkChanged$
            .pipe(takeUntil(this.unsubscribe$))
            .subscribe(newLink => this.detailsLink = newLink)
    }
}
Andrei Gătej
  • 11,116
  • 1
  • 14
  • 31
  • 1
    this is the way to go about this, could even be improved by the use of the async pipe rather than using the `unsubscribe` signal method. checking some service property on every change detection cycle will never perform well. This is what subjects are for. – bryan60 Nov 26 '19 at 21:38