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.
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;
}