I would like to configure my Angular component, so that the page only loads if the ID in the URL is valid. The point here is, that I want to protect the page from users manually entering a random URL, and accessing any page.
I have a component with lists.
If I click on the "Show Details", Angular navigates to the details page. I would like to only open this page, if the entered URL contains a valid ID. To achieve this, I call a service to gather all IDs into an array of strings. And then examine if the entered ID is a member of that array.
What I have tried:
list.component.ts:
ngOnInit() {
this.fetchLists();
}
fetchLists() {
from(this.listService.getGroups())
.pipe(
takeUntil(this.destroy$)
)
.subscribe({
next: (listUI: ListUI[]) => {
this.listData = listUI;
},
error: (error) => {
this.logger.debug(error.message);
this.certError = true;
}
});
}
details.component.ts:
ngOnInit() {
this.fetchListsAndIDs();
if (this.validIDsList.includes(listID)) {
this.router.navigateByUrl(`/groups/lists/${listID}/details`);
}
else {this.router.navigateByUrl(`/groups/lists`);}
}
fetchListsAndIDs() {
from(this.listService.getGroups())
.pipe(
takeUntil(this.destroy$)
)
.subscribe({
next: (listUI: ListUI[]) => {
const listData = listUI;
this.validIDsList = listData.map((lists) => lists.id);
},
error: (error) => {
this.logger.debug(error.message);
this.certError = true;
}
});
}
app.routing.module.ts
{
path: 'groups/lists/${listID}/details',
component: DetailsComponent
}
The page "groups/lists/99999999999/details" opens, with zero data, and "this.validIDsList" is undefined. Can someone please help me how to fix this?
CodePudding user response:
You almost have the right code, but you missed the part that, this.fetchListsAndIDs()
is executing an asynchronous observable, so your if..else
block is executing before even the API call completes.
I would suggest, you include the if...else
check inside the next()
handler. I have reversed the conditions to check for NOT first, since you are already in details.components.ts
which represents ``/groups/lists/${listID}/details)
route, you should only redirect the user back to lists
if id is not valid, else the component should continue with its work.
I added code to grab the listId
from URL. It is missing in the code you posted in the question.
ngOnInit() {
this.listID = this.route.snapshot.paramMap.get('listID');
this.fetchListsAndIDs();
}
fetchListsAndIDs() {
from(this.listService.getGroups())
.pipe(
takeUntil(this.destroy$)
)
.subscribe({
next: (listUI: ListUI[]) => {
const listData = listUI;
this.validIDsList = listData.map((lists) => lists.id);
this.handleNavigation();
},
error: (error) => {
this.logger.debug(error.message);
this.certError = true;
}
});
}
handleNavigation() {
if (!this.validIDsList.includes(this.listID)) {
this.router.navigateByUrl(`/groups/lists`);
} else {
// call the function to continue with details component
}
}