1

I have an iterator and the idea is to create a sub-view (for editions, smoother display etc.). The linkage works as supposed to and the strategy was to fetch the subset of the data upon load of the sub.view component. Due to legal and financial issues, we prefer to provide the already loaded data and feed the sub-view from the super-view instead of from the API.

<div *ngFor="let item of items">
  <a routerLink="{{'feature/subview/'}}"
     [queryParams]="{origin: ...,data:item}">Click me for {{item.name}}</a>
  {{item.this}} and {{item.that}} ...
</div>

I discovered that, although the item values are available to the super-component and render as expected, when the routing occurs, the query string contains the text [Object object] and not the actual serialization of it. How do I force serialization of item that's being passed along in the query string?

Alternatively, should I pass the data using other means than query string? The passed data will always be small, perhaps 1000 characters at the extreme maximum, often below 100 characters, so it made sense to use query strings but I'm open to other approaches, as long as it's not an overkill.

Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438
  • Why not create a service so the two components can talk to each other? – moritzg Feb 01 '20 at 16:55
  • How about using a service for inter component communication, or if the item has a unique id, you can use a service in combination with a route resolver to get the right data based on a router parameter. Your route will be like `feature/subview/:itemId` – Poul Kruijt Feb 01 '20 at 16:56
  • @moritzg That's one way. I was hoping not to have to move the data management to the service. Also, as a secondary reason, I'd like to use the component to render the passed data sessionlessly and statelesly. I know I can build that logic into the service too but all that requires some work and I'm hoping for a solution based on serialization into the query string for now. – Konrad Viltersten Feb 01 '20 at 17:09
  • @PierreDuc Please see the comment to the very similar suggestion above. – Konrad Viltersten Feb 01 '20 at 17:10
  • @KonradViltersten Well then I'd say serialize to JSON, and then parse again on the receiving side. – moritzg Feb 01 '20 at 17:35

1 Answers1

1

Good coding standards require splitting of responsibility. This definitely requires a service, to handle the getting and setting of the data. Components are meant to be dumb, and should only accept data, either from a service, input, or a state management system.

Those standards aside, there are two other ways you could just use the query string, and have it pretty. Use the JSON.stringify and JSON.parse methods to get and set the queryParams.

<a routerLink="feature/subview" [queryParams]="getQueryParams(item)">
  Click me for {{item.name}}
</a>
getQueryParams(item): any {
  return { query: JSON.stringify({
    origin: ...,
    data:item
  }) };
}

You can then obtain this query in your other component:

constructor(private route: ActivatedRoute) {}

ngOnInit(): void {
  // ignoring possible obvious undefined errors
  const item = JSON.parse(this.route.snapshot.params.query).query;
}

Another way could be to use the toString() method:

<a routerLink="feature/subview" [queryParams]="getQueryParams(item)">
  Click me for {{item.name}}
</a>
getQueryParams(item): any {
  return {
    origin: ...,
    data: item,
    toString() {
      return JSON.stringify(this)
    }
  };
}

I believe you no longer need to use the JSON.parse for your snapshot, but I could be wrong

constructor(private route: ActivatedRoute) {}

ngOnInit(): void {
  const { origin, data } = this.route.snapshot.params;
}
Poul Kruijt
  • 69,713
  • 12
  • 145
  • 149
  • 1
    Feel almost ashamed seeing you've put together a very clean and nice suggestion resolving the exact requirement stated, while I'm using the original suggestion for alternative approach, hahaha. I'd bounty you for the effort but you're bigger than me and probably don't give a rodent's sitting device... – Konrad Viltersten Feb 01 '20 at 18:38
  • @KonradViltersten that's alright :D glad you went for a service. That's indeed the way to go in your situation! Happy I could help nevertheless – Poul Kruijt Feb 01 '20 at 18:57