I have an issue where my component is re-initializing when I route to it with new parameters. Here are my routes.
const appRoutes: Routes = [
{ path: '', component: MyNewComponentComponent },
{ path: 'tiles', component: DisplayTileData },
{ path: 'tiles/:master/:filters', component: DisplayTileData }
];
I route to "tiles" and do a service call to fetch some data. I then have a couple of buttons that route back to the same component with values for "master" and "filters". Routing back to the component with parameters re-initializes the component and repeats the service call. I also have a text input on the page. When I first route to this component and add text, the route with parameters is also wiping out that text.
<a *ngFor="let tile of tiles">{{tile.id}}</a><br/><br/>
<input class="form-control" maxlength="30" minlength="3" name="from" ng-reflect-maxlength="30">
<button (click)="addNumberToFilter(15)"></button>
<button (click)="addNewMasterPath('do')">add new Number to Filter</button>
Is there a way to prevent this route re-initialization when routing with new parameters.
I have defaults values for the buttons. Here are the methods.
public variable: any = [3,4];
public master: any = 'eat';
addNewMasterPath(newMasterVariable) {
this.master = this.master + '-' + newMasterVariable;
var newMap = this.variable.map(items => { return items}).join('-');
this.router.navigate(['tiles/', this.master, newMap]);
}
addNumberToFilter(newParameter) {
this.variable.push(newParameter);
var newMap = this.variable.map(items => { return items}).join('-');
this.router.navigate(['tiles/', this.master, newMap]);
}
Routing back to the component with parameters re-initializes the component and repeats the service call.
That is because the new route where you go is specified as a different route in your application. For the component not to be reinitialized, it has to be the same route.
I see different possibilities here, depending on your specific scenario:
If you only load /tiles to make a service call and then route to tiles/:master/:filters
, but /tiles component doesn't make sense without receiving this data, you could consider using a resolver to make the API call, and then having only tiles/:master/:filters
route.
From the official docs, you can do the service call inside the resolver:
@Injectable()
export class MasterFiltersResolver implements Resolve<MasterFilter> {
constructor(private cs: MasterFiltersService, private router: Router) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<Crisis> {
let id = route.params['id'];
return this.cs.getData(id).then(data => {
if (data) {
return data;
}
});
}
}
Then in your route you can specify it as:
{ path: '', component: MyNewComponentComponent },
{ path: 'tiles/:master/:filters', component: DisplayTileData,
resolve: {
masterFilters: MasterFilterResolver
}
}
This way, it will retrieve the data you need before loading your component.
If your /tiles route component makes sense as a standalone component without master and filters data:
In this case, you can use optional parameters.
When having optional parameters, you would have only this route on your route definition
{ path: '', component: MyNewComponentComponent },
{ path: 'tiles', component: DisplayTileData }
And then navigating to this route through router.navigate('/tiles', {master: '', filter: ''}
.
In this case, your component will need something like:
constructor(private route: ActivatedRoute) {}
this.route.params.subscribe(params => {
// do something
});
this.route.params
is an observable of params, so you can be reactive to any change to do async operations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With