-1

I have a service (LocationService) that contains the user's country based on his gps coordinates and the functions to get the gps coordinates and do the reverse geocoding. My idea is to use the service to store the country and if the value is null then execute the function that gets the country.

I want to store it on a service because on my routes I call services that call the LocationService before performing any api call.

As I need to do this on all my routes is it any way to check if I have the country stored on the service, or if it's not the case get user location, before loading any route? Like a guard that checks if the user is logged.

The other alternative would be to set a function on the ngOnInit of every smart component of each route.

jcobo1
  • 1,065
  • 1
  • 18
  • 34

3 Answers3

2

I guess the best practice for this would be resolver usage. Just add layout layer under parent route for all your pages where need to use this resolver, or guard either. As from Angular documentation example:

RouterModule.forRoot([
      {
        path: 'detail/:id',
        component: CountryDetailComponent,
        resolve: {
          country: CountryResolver
        }
      }
    ])

And resolver is just like another service, but executes before routing. Important thing: it is wait for resolver finished with resolve function and only then apply routing. Example:

@Injectable({ providedIn: 'root' })
export class CountryResolver implements Resolve<Country> {
  constructor(private service: YourService) {}

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<any>|Promise<any>|any {
    return this.service.getCountry(route.paramMap.get('id'));
  }
}
Anton Marinenko
  • 2,749
  • 1
  • 10
  • 16
0

Is your 'service' of values an observable? If so you could do an ngIf on your observable, that will dynamically update when the async operation has data.

location$: Observable<any> = this.service.getData()

<ng-container *ngIf="{locations: location$ | async} as data; else loading">
    <a href="">{{data.location.URL}}
</ng-container>
<ng-template #loading>
    <p>There is no data to display
</ng-template>
0

you can use resolver for this work, but interface Resolve is deprecated in v15. you should use Function type(ResolveFn)

Function type definition for a data provider. A data provider can be used with the router to resolve data during navigation. The router waits for the data to be resolved before the route is finally activated. The following example implements a function that retrieves the data needed to activate the requested route.

const routes: Routes = [
  {
    path: '',
    component: yourComponent,
    resolve: {data: (route, state) => inject(yourService).resolve(route, state)}
  },
];

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

************************************************

export class YourService {

  constructor() {
  }

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<any> | Promise<any> | any {

  }
}