Home > Mobile >  Check if data in URL is valid before navigate to page
Check if data in URL is valid before navigate to page

Time:07-25

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. component

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

  • Related