13

I have [routerLink] as below;

 <li *ngFor="let item of pageNumbers" class="page-item">
      <a
        class="page-link"
        [routerLink]="getPageUrl(item) | async"
        routerLinkActive="active"
        >{{ item }}</a
      >
    </li>

And getPageUrl method is like;

public getPageUrl(pageNumber: number): Observable<string> {
    const url: Observable<string> = this.route.url.pipe(
      map((segments: UrlSegment[]) => {
        let segmentsString = segments.join("/");
        let pageUrl = `/${segmentsString}?startIndex=${pageNumber}`;
        return pageUrl;
      })
    );
    return url;
  }

But on browser angular shows url like below;

http://localhost:3005/documents%3FstartIndex%3D1 

desired:

http://localhost:3005/documents?startIndex=1

Am I missing something here? I would simply bind pagination directly to [routerLink], but there will be more query string parameters (filters, sorting) will get in to URL, that’s why I am trying to generate URL dynamically.

4
  • can you check this Commented Mar 23, 2020 at 4:37
  • URL you supplied mentions about router.navigate(). I don't want to handle that, I want my generated URL to be appeared non-encoded. Commented Mar 23, 2020 at 4:39
  • there is a answer about navigate by url check that Commented Mar 23, 2020 at 4:40
  • I don't want to navigate dynamically. I want URL to be appear once you mouse over the href, so people can bookmark it. Commented Mar 23, 2020 at 4:40

1 Answer 1

15

Check the docs for RouterLink:

  • [routerLink] is used to pass what comes before the ?, called "params".
  • [queryParams] is used to pass what comes after the ?, called "query params".

So, to solve your issue, a possible solution is to return an object from getPageUrl instead of a string, the object will have both the params and query params:

public getPageUrl(pageNumber: number): Observable<string> {
    return this.route.url.pipe(
      map((segments: UrlSegment[]) => {
        return {params: segments, queryParams: {startIndex: pageNumber};
      })
    );
  }

and you use it like this:

<a *ngIf="getPageUrl(item) | async as url"
   class="page-link"
   [routerLink]="url.params"
   [queryParams]="url.queryParams">{{ item }}</a

Notice you don't need to join the query segments with /, because routerLink accepts an array too.

Sign up to request clarification or add additional context in comments.

5 Comments

I just noticed queryParams is the thing I need to use. Thanks for the helpful post.
You don't need to conouted the URL at all. Just pass routerLink="." and then the queryParams. Essentially no TS needed for this.
Also make sure to take a look at queryParamsHandling if you have other query parameters as well.
queryParamsHandling with merge promising, I did not notice that. Thanks!
what if we get url from an api and not the angular router? how should we parse it and split url/queryparams?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.