0

I have an app with 3 routes:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { SearchComponent } from './pages/search/search.component';
import { CreateUserComponent } from './pages/create-user/create-user.component';
import { UserProfileComponent } from './pages/user/user-profile.component';

const routes: Routes = [
  {
    path: '',
    redirectTo: 'search',
    pathMatch: 'full'
  },
  {
    path: 'search',
    component: SearchComponent,
    data: {
      breadcrumb: 'Search'
    }
  },
  {
    path: 'create-user',
    component: CreateUserComponent,
    data: {
      breadcrumb: 'Create User'
    }
  },
  {
    path: 'user/:auth0Id',
    component: UserProfileComponent,
    data: {
      breadcrumb: 'Profile'
    }
  },
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class UserManagementRoutingModule { }

In the SearchComponent template, I have a button that make a GET request when clicked:

search.component.html

 <button nz-button nzType="primary" type="button"
  (click)="searchAll()">{{ 'SEARCH.SEARCH-FORM.SEARCH-ALL-BTN' | translate }}</button>

search.component.ts

    searchAll(): void {
    this.tableLoadingText = 'SEARCH.RESULT.LOADING-SEARCH';
    this.isTableLoading = true;
    this.currentSearchType = 'searchAll';

    this.scimB2bService.getAllUsers(this.pageSize, this.pageIndex).subscribe((res: IB2bScimUserList) => {
      this.userList = res.Resources;
      this.totalUser = res.totalResults;
      this.mapUsers(this.userList);
      this.triggerFeedback('success', 'SEARCH.STATUS.SUCCESS.SEARCH-ALL', null);
    }, error => {
      this.isTableLoading = false;
      this.triggerFeedback('error', 'SEARCH.STATUS.ERROR.SEARCH-ALL', error);
    });
  }

What's the easiest way to go to 'user/:auth0Id' route and comme back to 'search' route without loosing the search results (I mean not having to do the GET request again)?

Thanks!

analuspi
  • 184
  • 1
  • 1
  • 10
  • You should use ngOnDestroy on your search component and in this lifecycle hook store all latest data in your service file in a BehaviourSubject maybe, like `this.searchService.searchData.next(YOUR_SEARCH_DATA)` this. When the search component loads, ngOnInit() can bring that data back. This is one way of doing it. I would prefer doing this if your data is huge. If not, it is better to call the GET method again by hitting the search API with the search string. – Anglesvar Jul 26 '22 at 15:49
  • I used this approach: https://stackoverflow.com/a/44854611/14530862 combined with this other one: https://stackoverflow.com/a/57027024/14530862 – analuspi Jul 28 '22 at 18:19

2 Answers2

1

If you want data to be shared between components, just put it in a shared service.

@Injectable({providedIn: 'root'})
export class SearchService {
  searchResults = []; // idk if your results are actually an array
}

In your search component

constructor(private searchService: SearchService){}

searchAll(): void{
  ...
  this.scimB2bService.getAllUsers(this.pageSize, this.pageIndex).subscribe((res: IB2bScimUserList) => {
    this.searchService.searchResults = res.Resources; // idk what you actually want stored
    ...
  }); 
}

In any other component

constructor(private searchService: SearchService){}

get searchResults() { return this.searchService.searchResults };
<p *ngFor="let res of searchResults">{{ res }}</p>

It would make more sense to put the search functions and http requests in this service as well.

Since the service is provided in 'root', the enclosed data will persist as long as the application does.

Chris Hamilton
  • 9,252
  • 1
  • 9
  • 26
0

I used this approach: stackoverflow.com/a/44854611/14530862 combined with this other one: stackoverflow.com/a/57027024/14530862

My code:

import { ActivatedRouteSnapshot, RouteReuseStrategy, DetachedRouteHandle } from '@angular/router';



export class CustomReuseStrategy implements RouteReuseStrategy {
   private storedRouteHandles = new Map<string, DetachedRouteHandle>();

  // Decides if the route should be stored
  shouldDetach(route: ActivatedRouteSnapshot): boolean {
    return route.data.reuseRoute === true;
  }

  // Store the information for the route we're destructing
  store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
     this.storedRouteHandles.set(route.routeConfig.path, handle);
  }

 // Return true if we have a stored route object for the next route
  shouldAttach(route: ActivatedRouteSnapshot): boolean {
     return this.storedRouteHandles.has(route.routeConfig.path);
  }

  // If we returned true in shouldAttach(), now return the actual route data for restoration
  retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
     return this.storedRouteHandles.get(route.routeConfig.path);
  }

  // Reuse the route if we're going to and from the same route
  shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
     return future.routeConfig === curr.routeConfig;
  }
 }
analuspi
  • 184
  • 1
  • 1
  • 10