How to pass arbitrary (non parameterized) data to a route in Angular? - javascript

First : it's not a dup. The linked dup question's answer uses service which i'm not after it.
I have a routing table :
const routes: Routes = [
...
{ path: 'comp1', loadChildren: './module1/module1.module.ts#Module1Module' },
...
];
In the main component's ctor ( app.component.ts) i'm navigating to :
constructor(private router: Router){
router.navigate(['/comp1',{aaa:222,bbb:{ccc:3}}])
}
However - it is serialized to a URL.
https://angular-iqfnre-router.stackblitz.io/comp1;aaa=222;bbb=%5Bobject%20Object%5D
Now - I don't want it to appear in url. (not to mention that the value is not valid)
Also - the remote route in the lazy module is :
const routes: Routes = [
{
path: '', component: Comp1Component,
children: [{
path: 'acomp', component: AComponent,
}]
}
];
So it doesn't support parameters ( and i'm not talking about parameter but a complex data).
I don't want to change the route table.
Question:
How can I pass arbitrary (complex) data to the route - and how can I read it once i'm after routed ?
Stackblitz
NB
I don't want to use a service. I'm sure that there is another option to load the route with data. The docs mentioned NavigationExtras But I think it's still using URL.
(please - no stringify).

For this kind of requirements I would suggest using a shared service. With that you can pass the type of data you want without causing any additional overhead on the route.

Havn't had a chance to fully test this but seems to work on a simple route
altho currently it stringify's the object which isn't the best.
In a global component/service add
let routeData = null;
this.router.events
.filter((event) => (event instanceof ActivationStart || event instanceof ActivationEnd)).subscribe((event) => {
if (event instanceof ActivationStart) {
if(event.snapshot.params) {
let routeDataStr:string = event.snapshot.params.routeData;
if (routeDataStr) {
routeData = JSON.parse(routeDataStr);
if (event.snapshot.url[0]) {
this.router.navigate([event.snapshot.url[0].path]);
}
}
}
} else if (event instanceof ActivationEnd) {
let actEnd:ActivationEnd = event;
if (routeData) {
actEnd.snapshot.data = actEnd.snapshot.data == null ? {} : actEnd.snapshot.data;
actEnd.snapshot.data.routeData = routeData
}
}
})
Then to trigger the navigation use
let dataob:DataObject = {
blah: 123
}
this.router.navigate(['/comp1', {routeData: JSON.stringify(dataob)}]);
On the component that you just navigated to you can now access the data on the activeRoute
constructor(private route: ActivatedRoute, private router: Router) { }
ngOnInit() {
console.log(this.route.snapshot.data.routeData)
}

See the "Passing static data to a route" section in https://yakovfain.com/2015/11/11/angular-2-passing-data-to-routes:
Passing static data to a route
While most of the times parent components will be passing data to
their children, Angular also offers a mechanism to pass additional
data to components at the time of the route configuration. For
example, besides the dynamic data like product ID we may need to pass
a flag indicating if the application runs in production environment or
not. This can be done by using the data property of your route
configuration. For example, our route for the product details can be
configured as follows:
{path: 'product/:id', component: ProductDetailComponentParam ,
data: [{isProd: true}]}
The data property can contain an array of arbitrary string key-values
pairs. When the router will open ProductDetailComponentParam the data
value will be located in the data property of the
ActivatedRoute.snapshot:
export class ProductDetailComponentParam {
productID: string;
isProdEnvironment: string;
constructor(route: ActivatedRoute) {
this.productID = route.snapshot.params['id'];
this.isProdEnvironment = route.snapshot.data[0]['isProd'];
}
}
Passing data to a route via the data property is not an alternative to
configuring parameters in the path property as in path: ‘product/:id’
but can come handy when you need to pass some data to a route during
the configuration phase, e.g. is it a production or QA environment.

Related

NodeJS Accessing an object in the parent class constructor from the Child Class

What I'm attempting is to create a Controller Class that will initialize all my routes for me with ExpressJS here's a basic example of what I have
class Test extends Controller {
constructor(App) {
const Routes = [
{
url: '/hello',
execute: this.world
}
];
super({ Routes });
};
world(req, res) {
return res.json({success: true, msg: "Hello World."});
}
}
Controller Class
class Controller {
constructor({ Routes }) {
// I want to be able to access the items from the Routes Object here so I can loop over them and initialize them
}
}
I need a way to pass this routes Object into the Controller class, It needs to have the URL so that if a route has params such as /hello/:id then that would be defined there and it needs to know which function to execute in the Test class.
The issue is Your not allowed to access the this parameter before the super has been called and you can't access it within the super either. Is there any way that I can get this object through?
Is this possible or am I missing something really obvious
Define your routes as a static const routes and pass the child class in the constructor as
super(Test)
From the parent, you can access in the constructor
constructor(Test) {
this.routes = Test.routes
}
This should solve the problem.

Dynamically create route

My app is having some roles e.g Student, Teacher, etc. I have a route defined as
const routes : Routes = [
{ path : '', component : StudentDashboard }
]
I was wondering If I can replace StudentDashboard with TeacherDashboard dynamically based on the role. The data about role is present in a service.
I tried this
const routes : Routes = [
{ path : '', component : true ? StudentDashboard : TeacherDashboard }
]
This was not giving any compilation error. But how can I fetch the role from service so that I can replace condition in ternary expression.
What I am not looking for is
1) Re routing 2) Conditional child component
I am looking for manipulating route definition, I dont know if it is possible or not but giving it try
Why not just put both paths in your routing module:
const routes : Routes = [
{ path : 'teacher', component : TeacherDashboard },
{path:'student', component : StudentDashboard}
];
and when you are navigating you can check from from the service:
if(yourService.role === 'student') {
this.router.navigate(['/student']);
} else {
this.router.navigate(['/teacher']);
}
well if the path should be empty then you can use structural directive ngIf like:
<app-student *ngIf="role === 'student'"></app-student>
<app-teacher *ngIf="role === 'teacher'"></app-teacher>
In the component.ts you can get the role from service:
role: string;
ngOnInit() {
this.role = yourservice.role;
}
I would create another general component called 'dashboard' where in this class there are 2 variables that have type TeacherDashboard and StudentDashboard.
In app-routing I would set { path : ':id', component : DashBoardComponent }
in the Dashboard
student: StudentDashboardComponent;
teacher: TeacherDashboardComponent;
role: boolean;
// httpService is the service file where u call your api
counstructor(private router: Router, private http: HttpService) {}
ngOnInit() {
const id = this.router.url.substring(0);
this.http.searchTeacher(id).subscribe(
res => {
role = true; //true for teacher and false for student
}); // if u get err 404, it doesn't care
this.http.searchStudent(id).subscribe(
res => {
role = false; //true for teacher and false for student
},
err => {
console.log(err);
... do something...
});
-do your staff-
}
U have to adapt this code to your project, but I did that in my project and it work perfectly fine, u can also optimize all this stuff combining teacherDashboard with studentDashboard and with *ngIf on the role u can do all what u want to do.
I hope I was helpful.

Vue, is there a way to pass data between routes without URL params?

I am looking how to pass data secretly between two separate components (not parent and child) without using URL params in my Vue2 app. This doesn't mean I am passing secrets but rather I just dont want the user to see it (only for UI considerations).
I know Vue has Props but they are meant for passing data between parent and child component.
In my case, my URL will change but I don't want to pass data via visible params.
Someone claimed to use props without URL params here but I haven't been able to reproduce a working solution (getting undefined each time).
I also checked out these options but they are all using either URL or query params which as we know are visible.
An ugly solution would be to write the data to local storage and then read it there but this creates a lot of overhead and complexity (like what if I only want this data to be read once, etc).
Is there a more elegant solution to this problem?
Thanks!
make props: true for the destination route -- in the index.js file of router
{
path: '/home',
name: 'home',
component: taskChooser,
props: true,
}
define prop in the component e.g props: ['myprop'], - note the quotes
copy the variable you want to pass from the source route into the same name as your prop - in this case myprop
myprop = theVariableThatYouWantToPass
this.$router.replace({name:'home', params:{myprop}});
Make sure that the name of prop and variable are same - the prop is in quotes.
It's working for me.
Thanks #Mayank for pointing me in the correct direction.
Here is the correct syntax that worked for me.
Notice the props in In router index
{
path: '/componentPath',
name: 'componentName',
props: {
header: true,
content: true
},
}
In the component you are redirecting to, define the props as following:
props: {
myProperty: {
type: <DATATYPE>
},
}
Perform redirect as following:
this.$router.push({
name: 'componentName',
params: {
myProperty: <VARIABLE>
}
})
Access props with the this. convention from created or in later lifecycle event.
In this case, the variable name and property name do not have to be the same as it is a simple map. That naming convention would be a curious design choice anyway.
I haven't tested this in Vue 2, but in Vue 3, you can pass a stringified object through the props when you click on a link:
Add props: true to your routes file, for the route.
{
path: 'receipt',
name: 'receipt',
component: () => import('../pages/Receipt.vue'),
props: true,
beforeEnter(to, from, next) {
if (!to.params.receiptData) {
return next({
name: 'dashboard',
params: {
locale: from.params.locale ? from.params.locale : 'en',
},
});
}
return next();
},
},
Include your stringified object as a param for router.push().
const receiptData = {
transferType: 'default',
recipient: receiver.value.name,
referenceNumber: '#B3423424234',
amountSent: formAmount,
transferFee: 0,
};
router.push({
name: 'receipt',
params: {
receiptData: JSON.stringify(receiptData),
},
});
Declare the props as instance data in the component.
<script setup>
import { computed } from 'vue';
const props = defineProps({
receiptData: {
type: String,
required: true,
},
})
console.log('receiptData', props.receiptData);
const parsedReceiptData = computed(() => JSON.parse(props.receiptData));
</script>
I haven't tested an upper limit for size, so be careful about passing a huge object through, and you'll notice I showed a beforeEnter middleware on the route too because, if the user presses F5 to refresh the page, the props will be lost, so in my case, I redirect the user away from the page because the receipt is for one time use only.

Angular: Find key/value in nested array

Description:
I have a module.ts which has a const route which handles Routing. In this route, I have a key under data called sidebar.
const routes: Routes = [{
path: 'devices',
component: BaseComponent,
children: [{
path: '',
component: DeviceListComponent,
data: {
sidebar: true
}
}]
}];
What I want to do:
I want to be able to go through this array in my component.ts and if sidebar is found, and the value of sidebar is true, the path name will show up in a div.
For example, for path:'device', sidebar is true, so my div will have a text in it saying device.
What I tried to do/Problem(s):
I can't figure out how to find the sidebar key. In my component.ts file, I can succesfully get the array through router.config, but I can't figure out the logic to find the key.
ngOnInit() {
var theArray= this.router.config; //Grabs array successfully!
for (let obj of theArray) {
console.log("object:", theArray); //prints our array
for (let sidebar in obj) {
console.log("key:", sidebar, "value:", obj[sidebar]);
}
}
}
The result I get from my second console.log is:
I think the main problem here is that you shouldn't be doing what you are doing :)
There is a way to achieve what you want to do, of course, by parsing the router config in some complicated way - but what you want to achieve, can be done way easier by using the intended way instead.
One way would be for example to use the resolve-data functionality of Angular in order to get the variable you need into your component.
So your route would look something like this
{
path: '',
component: DeviceListComponent,
resolve: {
sidebar: true
}
}
whilst in your component you would do something like this
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.hasSidebar= this.route.snapshot.data['sidebar'];
}
for a more in-depth tutorial on that topic you might check out this blog post for example:
https://blog.thoughtram.io/angular/2016/10/10/resolving-route-data-in-angular-2.html
Perhaps there is a more "Angular" way of doing this, but if not, you need to look deeper into that route object.
ngOnInit() {
var theArray= this.router.config; //Grabs array successfully!
for (let config of theArray) {
const path = config.path;
if ('children' in config) {
const child = config['children'][0];
if ('data' in child && child['data'].sidebar) {
// do whatever you need in here
}
}
}
}

Change route params without reloading in Angular 2

I'm making a real estate website using Angular 2, Google Maps, etc. and when a user changes the center of the map I perform a search to the API indicating the current position of the map as well as the radius. The thing is, I want to reflect those values in the url without reloading the entire page. Is that possible? I've found some solutions using AngularJS 1.x but nothing about Angular 2.
As of RC6 you can do the following to change URL without change state and thereby keeping your route history
import {OnInit} from '#angular/core';
import {Location} from '#angular/common';
// If you dont import this angular will import the wrong "Location"
#Component({
selector: 'example-component',
templateUrl: 'xxx.html'
})
export class ExampleComponent implements OnInit
{
constructor( private location: Location )
{}
ngOnInit()
{
this.location.replaceState("/some/newstate/");
}
}
You could use location.go(url) which will basically change your url, without change in route of application.
NOTE this could cause other effect like redirect to child route from the current route.
Related question which describes location.go will not intimate to Router to happen changes.
Using location.go(url) is the way to go, but instead of hardcoding the url , consider generating it using router.createUrlTree().
Given that you want to do the following router call: this.router.navigate([{param: 1}], {relativeTo: this.activatedRoute}) but without reloading the component, it can be rewritten as:
const url = this.router.createUrlTree([], {relativeTo: this.activatedRoute, queryParams: {param: 1}}).toString()
this.location.go(url);
For anyone like me finding this question the following might be useful.
I had a similar problem and initially tried using location.go and location.replaceState as suggested in other answers here. However I ran into problems when I had to navigate to another page on the app because the navigation was relative to the current route and the current route wasn't being updated by location.go or location.replaceState (the router doesn't know anything about what these do to the URL)
In essence I needed a solution that DIDN'T reload the page/component when the route parameter changed but DID update the route state internally.
I ended up using query parameters. You can find more about it here: https://angular-2-training-book.rangle.io/handout/routing/query_params.html
So if you need to do something like save an order and get an order ID you can update your page URL like shown below. Updating a centre location and related data on a map would be similar
// let's say we're saving an order. Initally the URL is just blah/orders
save(orderId) {
// [Here we would call back-end to save the order in the database]
this.router.navigate(['orders'], { queryParams: { id: orderId } });
// now the URL is blah/orders?id:1234. We don't reload the orders
// page or component so get desired behaviour of not seeing any
// flickers or resetting the page.
}
and you keep track of it within the ngOnInit method like:
ngOnInit() {
this.orderId = this.route
.queryParamMap
.map(params => params.get('id') || null);
// orderID is up-to-date with what is saved in database now, or if
// nothing is saved and hence no id query paramter the orderId variable
// is simply null.
// [You can load the order here from its ID if this suits your design]
}
If you need to go direct to the order page with a new (unsaved) order you can do:
this.router.navigate(['orders']);
Or if you need to go direct to the order page for an existing (saved) order you can do:
this.router.navigate(['orders'], { queryParams: { id: '1234' } });
I had major trouble getting this to work in RCx releases of angular2. The Location package has moved, and running location.go() inside constructor() wont work. It needs to be ngOnInit() or later in the lifecycle. Here is some example code:
import {OnInit} from '#angular/core';
import {Location} from '#angular/common';
#Component({
selector: 'example-component',
templateUrl: 'xxx.html'
})
export class ExampleComponent implements OnInit
{
constructor( private location: Location )
{}
ngOnInit()
{
this.location.go( '/example;example_param=917' );
}
}
Here are the angular resources on the matter:
https://angular.io/docs/ts/latest/api/common/index/Location-class.html
https://angular.io/docs/ts/latest/api/common/index/LocationStrategy-class.html
I've had similar requirements as described in the question and it took a while to figure things out based on existing answers, so I would like to share my final solution.
Requirements
The state of my view (component, technically) can be changed by the user (filter settings, sorting options, etc.) When state changes happen, i.e. the user changes the sorting direction, I want to:
Reflect the state changes in the URL
Handle state changes, i.e. make an API call to receive a new result set
additionally, I would like to:
Specify if the URL changes are considered in the browser history (back/forward) based on circumstances
use complex objects as state params to provide greater flexibility in handling of state changes (optional, but makes life easier for example when some state changes trigger backend/API calls while others are handled by the frontend internally)
Solution: Change state without reloading component
A state change does not cause a component reload when using route parameters or query parameters. The component instance stays alive. I see no good reason to mess with the router state by using Location.go() or location.replaceState().
var state = { q: 'foo', sort: 'bar' };
var url = this.router.createUrlTree([], { relativeTo: this.activatedRoute, queryParams: state }).toString();
this.router.navigateByUrl(url);
The state object will be transformed to URL query params by Angular's Router:
https://localhost/some/route?q=foo&sort=bar
Solution: Handling state changes to make API calls
The state changes triggered above can be handled by subscribing to ActivatedRoute.queryParams:
export class MyComponent implements OnInit {
constructor(private activatedRoute: ActivatedRoute) { }
ngOnInit()
{
this.activatedRoute.queryParams.subscribe((params) => {
// params is the state object passed to the router on navigation
// Make API calls here
});
}
}
The state object of the above axample will be passed as the params argument of the queryParams observable. In the handler API calls can be made if necessary.
But: I would prefer handling the state changes directly in my component and avoid the detour over ActivatedRoute.queryParams. IMO, navigating the router, letting Angular do routing magic and handle the queryParams change to do something, completely obfuscates whats happening in my component with regards to maintenability and readability of my code. What I do instead:
Compare the state passed in to queryParams observable with the current state in my component, do nothing, if it hasn't changed there and handle state changes directly instead:
export class MyComponent implements OnInit {
private _currentState;
constructor(private activatedRoute: ActivatedRoute) { }
ngOnInit()
{
this.activatedRoute.queryParams.subscribe((params) => {
// Following comparison assumes, that property order doesn't change
if (JSON.stringify(this._currentState) == JSON.stringify(params)) return;
// The followig code will be executed only when the state changes externally, i.e. through navigating to a URL with params by the user
this._currentState = params;
this.makeApiCalls();
});
}
updateView()
{
this.makeApiCalls();
this.updateUri();
}
updateUri()
{
var url = this.router.createUrlTree([], { relativeTo: this.activatedRoute, queryParams: this._currentState }).toString();
this.router.navigateByUrl(url);
}
}
Solution: Specify browser history behavior
var createHistoryEntry = true // or false
var url = ... // see above
this.router.navigateByUrl(url, { replaceUrl : !createHistoryEntry});
Solution: Complex objects as state
This is beyond the original question but adresses common scenarios and might thus be useful: The state object above is limited to flat objects (an object with only simple string/bool/int/... properties but no nested objects). I found this limiting, because I need to distinguish between properties that need to be handled with a backend call and others, that are only used by the component internally. I wanted a state object like:
var state = { filter: { something: '', foo: 'bar' }, viewSettings: { ... } };
To use this state as queryParams object for the router, it needs to be flattened. I simply JSON.stringify all first level properties of the object:
private convertToParamsData(data) {
var params = {};
for (var prop in data) {
if (Object.prototype.hasOwnProperty.call(data, prop)) {
var value = data[prop];
if (value == null || value == undefined) continue;
params[prop] = JSON.stringify(value, (k, v) => {
if (v !== null) return v
});
}
}
return params;
}
and back, when handling the queryParams returned passed in by the router:
private convertFromParamsData(params) {
var data = {};
for (var prop in params) {
if (Object.prototype.hasOwnProperty.call(params, prop)) {
data[prop] = JSON.parse(params[prop]);
}
}
return data;
}
Finally: A ready-to-use Angular service
And finally, all of this isolated in one simple service:
import { Injectable } from '#angular/core';
import { ActivatedRoute, Router } from '#angular/router';
import { Observable } from 'rxjs';
import { Location } from '#angular/common';
import { map, filter, tap } from 'rxjs/operators';
#Injectable()
export class QueryParamsService {
private currentParams: any;
externalStateChange: Observable<any>;
constructor(private activatedRoute: ActivatedRoute, private router: Router, private location: Location) {
this.externalStateChange = this.activatedRoute.queryParams
.pipe(map((flatParams) => {
var params = this.convertFromParamsData(flatParams);
return params
}))
.pipe(filter((params) => {
return !this.equalsCurrentParams(params);
}))
.pipe(tap((params) => {
this.currentParams = params;
}));
}
setState(data: any, createHistoryEntry = false) {
var flat = this.convertToParamsData(data);
const url = this.router.createUrlTree([], { relativeTo: this.activatedRoute, queryParams: flat }).toString();
this.currentParams = data;
this.router.navigateByUrl(url, { replaceUrl: !createHistoryEntry });
}
private equalsCurrentParams(data) {
var isEqual = JSON.stringify(data) == JSON.stringify(this.currentParams);
return isEqual;
}
private convertToParamsData(data) {
var params = {};
for (var prop in data) {
if (Object.prototype.hasOwnProperty.call(data, prop)) {
var value = data[prop];
if (value == null || value == undefined) continue;
params[prop] = JSON.stringify(value, (k, v) => {
if (v !== null) return v
});
}
}
return params;
}
private convertFromParamsData(params) {
var data = {};
for (var prop in params) {
if (Object.prototype.hasOwnProperty.call(params, prop)) {
data[prop] = JSON.parse(params[prop]);
}
}
return data;
}
}
which can be used like:
#Component({
selector: "app-search",
templateUrl: "./search.component.html",
styleUrls: ["./search.component.scss"],
providers: [QueryParamsService]
})
export class ProjectSearchComponent implements OnInit {
filter : any;
viewSettings : any;
constructor(private queryParamsService: QueryParamsService) { }
ngOnInit(): void {
this.queryParamsService.externalStateChange
.pipe(debounce(() => interval(500))) // Debounce optional
.subscribe(params => {
// Set state from params, i.e.
if (params.filter) this.filter = params.filter;
if (params.viewSettings) this.viewSettings = params.viewSettings;
// You might want to init this.filter, ... with default values here
// If you want to write default values to URL, you can call setState here
this.queryParamsService.setState(params, false); // false = no history entry
this.initializeView(); //i.e. make API calls
});
}
updateView() {
var data = {
filter: this.filter,
viewSettings: this.viewSettings
};
this.queryParamsService.setState(data, true);
// Do whatever to update your view
}
// ...
}
Don't forget the providers: [QueryParamsService] statement on component level to create a new service instance for the component. Don't register the service globally on app module.
I use this way to get it:
const queryParamsObj = {foo: 1, bar: 2, andThis: 'text'};
this.location.replaceState(
this.router.createUrlTree(
[this.locationStrategy.path().split('?')[0]], // Get uri
{queryParams: queryParamsObj} // Pass all parameters inside queryParamsObj
).toString()
);
-- EDIT --
I think that I should add some more informations for this.
If you use this.location.replaceState() router of your application is not updated, so if you use router information later it's not equal for this in your browser. For example if you use localizeService to change language, after switch language your application back to last URL where you was before change it with this.location.replaceState().
If you don't want this behaviour you can chose different method for update URL, like:
this.router.navigate(
[this.locationStrategy.path().split('?')[0]],
{queryParams: queryParamsObj}
);
In this option your browser also doesn't refresh but your URL change is also injected into Router of your application, so when you switch language you don't have problem like in this.location.replaceState().
Of course you can choose method for your needs. The first is more lighter because you don't engage your application more than change URL in browser.
Use attribute queryParamsHandling: 'merge' while changing the url.
this.router.navigate([], {
queryParams: this.queryParams,
queryParamsHandling: 'merge',
replaceUrl: true,
});
For me it was actually a mix of both with Angular 4.4.5.
Using router.navigate kept destroying my url by not respecting the realtiveTo: activatedRoute part.
I've ended up with:
this._location.go(this._router.createUrlTree([this._router.url], { queryParams: { profile: value.id } }).toString())
In 2021 here is the solution I use. Create URL Tree using createUrlTree and navigate to route using location
//Build URL Tree
const urlTree = this.router.createUrlTree(["/employee/"+this.employeeId],{
relativeTo: this.route,
queryParams: params,
queryParamsHandling: 'merge'
});
//Update the URL
this.location.go(urlTree.toString());
In my case I needed to remove a query param of the url to prevent user to see it.
I found replaceState safer than location.go because the path with the old query params disappeared of the stack and user can be redo the query related with this query. So, I prefer it to do it:
this.location.replaceState(this.router.url.split('?')[0]);
Whit location.go, go to back with the browser will return to your old path with the query params and will keep it in the navigation stack.
this.location.go(this.router.url.split('?')[0]);
it's better to use activatedRoute.navigate() to change URL parameters and use snapshot (not subscribe) to call API if u don't want to call API when URL parameters change.
export class MyComponent implements OnInit {
constructor(private activatedRoute: ActivatedRoute) { }
ngOnInit()
{
const params = this.activatedRoute.snapshot.queryParams;
// params is the state object passed to the router on navigation
// Make API calls here
}
}
import { Component, OnInit } from '#angular/core';
import { Location } from '#angular/common';
#Component({
selector: 'child-component',
templateUrl: 'child.component.html',
styleUrls: ['child.component.scss']
})
export class ChildComponent implements OnInit {
constructor(
private location: Location
) {}
ngOnInit() {
// you can put 'this.location.go()' method call in any another method
this.location.go('parentRoute/anotherChildRoute');
}
}
For me, it changes child route in browser, without any current component reloading.
I was trying to update queryparams and navigate without reloading. By nature activatedRoute.snapshot.queryparams are readonly. And this turnaround approach solved my problem.
// Get queryparams
let state = Object.assign({}, this.route.snapshot.queryParams)
// Change parameters of url
state["z"] = "hi";
state["y"] = "bye";
// Create url and navigate to it without reloading
const url = this.router.createUrlTree([], { relativeTo: this.route, queryParams: state }).toString();
this.router.navigateByUrl(url);

Categories

Resources