Search code examples
angularangular-routing

Route to component as new tab and pass data to this component


I have a component that has a grid showing data. One of the columns contains the uniqueID for the data row and that has been templated as a button with an onclick event. The onclick event will open a new component as a new tab/page. This is my onclick code:

btnOpsE2EHistoryClick(uniqueID: string) {
   console.log('E2E history for UniqueID: ' + uniqueID);
   var navUrl = environment.siteURL + 'e2e-history/';
   window.open(navUrl + uniqueID, '_blank');
}

This works fine but I now need to send additional data which I don't want appear in the URL.

btnOpsE2EHistoryClick(uniqueID: string, evType: string) {
   console.log('E2E history for event: ' + evType + ' - UniqueID: ' + uniqueID);
   var navUrl = environment.siteURL + 'e2e-history/';
   window.open(navUrl + uniqueID, '_blank'); //HOW DO I pass the evType so that it does not appear in URL.
}

I have the following route configured:

{ path: 'e2e-history/:id', component: E2eHistoryComponent, title: 'E2E Log History' }

How would I go about this?


Solution

  • From what I understand based on your case, you want to sharing data between components, and you don't want to make the 'evtype' parameter part of the route URL.

    There are several ways for components to communicate with each other:

    1. Using EventEmitter
    2. Using a service
    3. Using NGRX Store

    In your case, I would recommend using communication via a service.

    Here are the steps you should follow:

    • Create a service to store and share data between components.

    • Modify the btnOpsE2EHistoryClick method to store the additional data in the service before opening the new tab/window.

    • Create a component to display the data received from the service in
      the new tab/window.

    First, create a service to store and share data (DONT FORGET TO ASSIGN THE SERVICE IN MODULE):

    import { Injectable } from '@angular/core';
    
    @Injectable({
      providedIn: 'root'
    })
    export class DataSharingService {
      private eventData: any;
    
      constructor() { }
    
      setEventData(data: any) {
        this.eventData = data;
      }
    
      getEventData() {
        return this.eventData;
      }
    }
    

    Next, modify your component to use the service:

    import { DataSharingService } from 'path/to/data-sharing.service';
    
    constructor(private dataSharingService: DataSharingService) {}
    
    btnOpsE2EHistoryClick(uniqueID: string, evType: string) {
       console.log('E2E history for event: ' + evType + ' - UniqueID: ' + uniqueID);
       
       // Store additional data in the service
       this.dataSharingService.setEventData({ uniqueID: uniqueID, evType: evType });
    
       // Open the new tab/window
       var navUrl = environment.siteURL + 'e2e-history/';
       window.open(navUrl + uniqueID, '_blank');
    }
    

    Finally, in the component of the new tab/window, retrieve the data from the service:

    import { DataSharingService } from 'path/to/data-sharing.service';
    
    constructor(private dataSharingService: DataSharingService) {}
    
    ngOnInit() {
      // Retrieve data from the service
      const eventData = this.dataSharingService.getEventData();
      console.log(eventData); // Do whatever you want with the data
    }
    

    This approach ensures that the additional data is shared between components without being exposed in the URL.