Search code examples
angulargoogle-maps-api-3rxjsangular-router-guards

Angular guard not returning data


I'm using google maps API to get maxLat,maxLng,minLat,minLng and then I want to resolve data from the database before create the component, this is for SEO metas and description

the problem is, that the guard is resolving the data, but not resolving the component

my GuardService.ts

@Injectable({
  providedIn: 'root'
})
export class BusquedaGuardService implements CanActivate {
  componentForm = {
    locality: 'long_name',
    administrative_area_level_2: 'short_name',
    administrative_area_level_1: 'short_name'
  };
  ubicacion: string
  maxLng
  minLng
  maxLat
  minLat
  constructor(private http: HttpClient,
    private router: Router,
    @Inject(PLATFORM_ID) private platformId: Object,
    private ngZone: NgZone,
    private mapaService: MapaService,
    private mapsAPILoader: MapsAPILoader) { }
  async getBounds() {
    let promise = new Promise((res, rej) => {
      this.mapsAPILoader.load().then(() => {
        this.ngZone.run(() => {
          let autocompleteService = new google.maps.places.AutocompleteService();
          autocompleteService.getPlacePredictions(
            {
              'input': this.ubicacion,
              'componentRestrictions': { 'country': 'cl' },
            },
            (list, status) => {
              if (list == null || list.length == 0) {
                // console.log("No results");
              } else {
                let placesService = new google.maps.places.PlacesService(document.createElement('div'));
                placesService.getDetails(
                  { placeId: list[0].reference },
                  (detailsResult: google.maps.places.PlaceResult, placesServiceStatus) => {
                    let direccion = ''
                    let contador = 0
                    for (var i = 0; i < detailsResult.address_components.length; i++) {
                      var addressType = detailsResult.address_components[i].types[0];
                      if (this.componentForm[addressType]) {
                        var val = detailsResult.address_components[i][this.componentForm[addressType]];
                        // $(`#${addressType}`).value = val;
                        if (addressType == 'locality') {
                          direccion = direccion + val
                          contador++
                        } else {
                          if (contador == 0 && addressType == "administrative_area_level_2") {
                            direccion = direccion + val
                            contador++
                          } else {
                            if (contador == 0 && addressType == "administrative_area_level_1") {
                              direccion = direccion + val
                            } else {
                              direccion = direccion + ", " + val
                            }
                          }
                        }
                      }
                    }
                    this.mapaService.setDireccion(direccion)
                    let e = detailsResult.geometry.viewport
                    let lat = e[Object.keys(e)[0]]
                    let lng = e[Object.keys(e)[1]]
                    // console.log(lat, lng)
                    this.maxLng = lng[Object.keys(lng)[1]]
                    this.minLng = lng[Object.keys(lng)[0]]
                    this.maxLat = lat[Object.keys(lng)[1]]
                    this.minLat = lat[Object.keys(lng)[0]]
                    let bounds = {
                      maxLat: this.maxLat,
                      maxLng: this.maxLng,
                      minLat: this.minLat,
                      minLng: this.minLng
                    }
                    this.mapaService.setBounds(this.maxLng, this.minLng, this.maxLat, this.minLat)
                    this.mapaService.setLatLng(detailsResult.geometry.location.lat(), detailsResult.geometry.location.lng())
                    console.log('aqui')
                    console.log(`${ipMarco}Instalaciones/Bounds/${this.maxLng}/${this.minLng}/${this.maxLat}/${this.minLat}`)
                    res(bounds)
                    // return this.http.get(`${ipMarco}Instalaciones/Bounds/${this.maxLng}/${this.minLng}/${this.maxLat}/${this.minLat}`).pipe(
                    //   map((res: any) => {
                    //     console.log(res)
                    //     return of(true)
                    //   }),
                    //   catchError(error => {
                    //     console.log('aqui')
                    //     console.log(error)
                    //     this.router.navigateByUrl('')
                    //     return of(false)
                    //   })
                    // )
                  }
                )
              }
            }
          );
        })
      })
    })
    let bounds = await promise
    console.log(bounds)
    return bounds
  }
  canActivate(route: ActivatedRouteSnapshot): Observable<any> {
    // return of(true)
    // console.log('aqui')
    if (route.queryParams['ubicacion']) {
      this.ubicacion = route.queryParams['ubicacion']
      if (this.ubicacion != undefined) {
        if (this.ubicacion != "") {
          return from(this.getBounds()).pipe(
            switchMap((bounds: any) => {
              return this.http.get(`${ipMarco}Instalaciones/Bounds/${bounds.maxLng}/${bounds.minLng}/${bounds.maxLat}/${bounds.minLat}`).pipe(
                map((res: any) => {
                  console.log(res)
                  return of(true)
                }),
                catchError(error => {
                  console.log('aqui')
                  console.log(error)
                  this.router.navigateByUrl('')
                  return of(false)
                })
              )
            })
          )
        }
      }
    }
  }
}

my app-routing.module.ts

const routes: Routes = [
  {
    path: '',
    component: InicioComponent
  },
  {
    path: 'busqueda',
    component: BusquedaComponent,
    canActivate: [BusquedaGuardService],
    resolve: { data: BusquedaResolveService }
  },
];

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

my resolve.service.ts

@Injectable({
  providedIn: 'root'
})
export class BusquedaResolveService {

  constructor(private mapaService:MapaService,
    private http:HttpClient) {
      console.log('nose')
    }
  resolve(route: ActivatedRouteSnapshot) {
    let maxLng = this.mapaService.getBoundsUnaVez().maxLng
    let minLng = this.mapaService.getBoundsUnaVez().minLng
    let maxLat = this.mapaService.getBoundsUnaVez().maxLat
    let minLat = this.mapaService.getBoundsUnaVez().minLat
    console.log(maxLng,minLng,maxLat,minLat)
    return this.http.get(`${ipMarco}Instalaciones/Bounds/${maxLng}/${minLng}/${maxLat}/${minLat}`);
  }
}

Edit

I realized my mistake, instead using a guard to get data I needed to use resolve this is my new resolve.service.ts:

import { Injectable, NgZone, PLATFORM_ID, Inject } from '@angular/core';
import { ActivatedRouteSnapshot, Router } from '@angular/router';
import { MapaService } from './mapa.service';
import { ipMarco } from 'src/global';
import { HttpClient } from '@angular/common/http';
import { MapsAPILoader } from '@agm/core';
import { isPlatformBrowser } from '@angular/common';

@Injectable({
  providedIn: 'root'
})
export class BusquedaResolveService {
  componentForm = {
    locality: 'long_name',
    administrative_area_level_2: 'short_name',
    administrative_area_level_1: 'short_name'
  };
  ubicacion: string
  maxLng
  minLng
  maxLat
  minLat
  constructor(private mapaService: MapaService,
    private http: HttpClient,
    private ngZone: NgZone,
    private router: Router,
    private mapsAPILoader: MapsAPILoader,
    @Inject(PLATFORM_ID) private platformId: Object,) {
  }
  async getBounds() {
    if (isPlatformBrowser(this.platformId)) {
      let promise = new Promise((res, rej) => {
        this.mapsAPILoader.load().then(() => {
          this.ngZone.run(() => {
            let autocompleteService = new google.maps.places.AutocompleteService();
            autocompleteService.getPlacePredictions(
              {
                'input': this.ubicacion,
                'componentRestrictions': { 'country': 'cl' },
              },
              (list, status) => {
                if (list == null || list.length == 0) {
                  // console.log("No results");
                } else {
                  let placesService = new google.maps.places.PlacesService(document.createElement('div'));
                  placesService.getDetails(
                    { placeId: list[0].reference },
                    (detailsResult: google.maps.places.PlaceResult, placesServiceStatus) => {
                      let direccion = ''
                      let contador = 0
                      for (var i = 0; i < detailsResult.address_components.length; i++) {
                        var addressType = detailsResult.address_components[i].types[0];
                        if (this.componentForm[addressType]) {
                          var val = detailsResult.address_components[i][this.componentForm[addressType]];
                          // $(`#${addressType}`).value = val;
                          if (addressType == 'locality') {
                            direccion = direccion + val
                            contador++
                          } else {
                            if (contador == 0 && addressType == "administrative_area_level_2") {
                              direccion = direccion + val
                              contador++
                            } else {
                              if (contador == 0 && addressType == "administrative_area_level_1") {
                                direccion = direccion + val
                              } else {
                                direccion = direccion + ", " + val
                              }
                            }
                          }
                        }
                      }
                      this.mapaService.setDireccion(direccion)
                      let e = detailsResult.geometry.viewport
                      let lat = e[Object.keys(e)[0]]
                      let lng = e[Object.keys(e)[1]]
                      // console.log(lat, lng)
                      this.maxLng = lng[Object.keys(lng)[1]]
                      this.minLng = lng[Object.keys(lng)[0]]
                      this.maxLat = lat[Object.keys(lng)[1]]
                      this.minLat = lat[Object.keys(lng)[0]]
                      let bounds = {
                        maxLat: this.maxLat,
                        maxLng: this.maxLng,
                        minLat: this.minLat,
                        minLng: this.minLng
                      }
                      this.mapaService.setBounds(this.maxLng, this.minLng, this.maxLat, this.minLat)
                      this.mapaService.setLatLng(detailsResult.geometry.location.lat(), detailsResult.geometry.location.lng())
                      console.log('aqui')
                      console.log(`${ipMarco}Instalaciones/Bounds/${this.maxLng}/${this.minLng}/${this.maxLat}/${this.minLat}`)
                      res(bounds)
                    }
                  )
                }
              }
            );
          })
        })
      })
      let bounds = await promise
      console.log(bounds)
      return bounds
    }
  }
  resolve(route: ActivatedRouteSnapshot): Promise<any> | boolean {
    if (route.queryParams['ubicacion']) {
      this.ubicacion = route.queryParams['ubicacion']
      if (this.ubicacion != undefined) {
        if (this.ubicacion != "") {
          return this.getBounds().then((bounds: any) => {
            return this.http.get(`${ipMarco}Instalaciones/Bounds/${bounds.maxLng}/${bounds.minLng}/${bounds.maxLat}/${bounds.minLat}`).toPromise()
              .then(respuesta => respuesta).catch(error => {
                console.log(error)
                this.router.navigateByUrl('')
                return false
              })
          })
        }
      }
    }
  }
}

and I deleted my guard, because I dont need it in this component


Solution

  • i solved by doing the operation in the resolve.service instead the guard

    this worked for me

    my resolve.service.ts

    import { Injectable, NgZone, PLATFORM_ID, Inject } from '@angular/core';
    import { ActivatedRouteSnapshot, Router } from '@angular/router';
    import { MapaService } from './mapa.service';
    import { ipMarco } from 'src/global';
    import { HttpClient } from '@angular/common/http';
    import { MapsAPILoader } from '@agm/core';
    import { isPlatformBrowser } from '@angular/common';
    
    @Injectable({
      providedIn: 'root'
    })
    export class BusquedaResolveService {
      componentForm = {
        locality: 'long_name',
        administrative_area_level_2: 'short_name',
        administrative_area_level_1: 'short_name'
      };
      ubicacion: string
      maxLng
      minLng
      maxLat
      minLat
      constructor(private mapaService: MapaService,
        private http: HttpClient,
        private ngZone: NgZone,
        private router: Router,
        private mapsAPILoader: MapsAPILoader,
        @Inject(PLATFORM_ID) private platformId: Object,) {
      }
      async getBounds() {
        if (isPlatformBrowser(this.platformId)) {
          let promise = new Promise((res, rej) => {
            this.mapsAPILoader.load().then(() => {
              this.ngZone.run(() => {
                let autocompleteService = new google.maps.places.AutocompleteService();
                autocompleteService.getPlacePredictions(
                  {
                    'input': this.ubicacion,
                    'componentRestrictions': { 'country': 'cl' },
                  },
                  (list, status) => {
                    if (list == null || list.length == 0) {
                      // console.log("No results");
                    } else {
                      let placesService = new google.maps.places.PlacesService(document.createElement('div'));
                      placesService.getDetails(
                        { placeId: list[0].reference },
                        (detailsResult: google.maps.places.PlaceResult, placesServiceStatus) => {
                          let direccion = ''
                          let contador = 0
                          for (var i = 0; i < detailsResult.address_components.length; i++) {
                            var addressType = detailsResult.address_components[i].types[0];
                            if (this.componentForm[addressType]) {
                              var val = detailsResult.address_components[i][this.componentForm[addressType]];
                              // $(`#${addressType}`).value = val;
                              if (addressType == 'locality') {
                                direccion = direccion + val
                                contador++
                              } else {
                                if (contador == 0 && addressType == "administrative_area_level_2") {
                                  direccion = direccion + val
                                  contador++
                                } else {
                                  if (contador == 0 && addressType == "administrative_area_level_1") {
                                    direccion = direccion + val
                                  } else {
                                    direccion = direccion + ", " + val
                                  }
                                }
                              }
                            }
                          }
                          this.mapaService.setDireccion(direccion)
                          let e = detailsResult.geometry.viewport
                          let lat = e[Object.keys(e)[0]]
                          let lng = e[Object.keys(e)[1]]
                          // console.log(lat, lng)
                          this.maxLng = lng[Object.keys(lng)[1]]
                          this.minLng = lng[Object.keys(lng)[0]]
                          this.maxLat = lat[Object.keys(lng)[1]]
                          this.minLat = lat[Object.keys(lng)[0]]
                          let bounds = {
                            maxLat: this.maxLat,
                            maxLng: this.maxLng,
                            minLat: this.minLat,
                            minLng: this.minLng
                          }
                          this.mapaService.setBounds(this.maxLng, this.minLng, this.maxLat, this.minLat)
                          this.mapaService.setLatLng(detailsResult.geometry.location.lat(), detailsResult.geometry.location.lng())
                          console.log('aqui')
                          console.log(`${ipMarco}Instalaciones/Bounds/${this.maxLng}/${this.minLng}/${this.maxLat}/${this.minLat}`)
                          res(bounds)
                        }
                      )
                    }
                  }
                );
              })
            })
          })
          let bounds = await promise
          console.log(bounds)
          return bounds
        }
      }
      resolve(route: ActivatedRouteSnapshot): Promise<any> | boolean {
        if (route.queryParams['ubicacion']) {
          this.ubicacion = route.queryParams['ubicacion']
          if (this.ubicacion != undefined) {
            if (this.ubicacion != "") {
              return this.getBounds().then((bounds: any) => {
                return this.http.get(`${ipMarco}Instalaciones/Bounds/${bounds.maxLng}/${bounds.minLng}/${bounds.maxLat}/${bounds.minLat}`).toPromise()
                  .then(respuesta => respuesta).catch(error => {
                    console.log(error)
                    this.router.navigateByUrl('')
                    return false
                  })
              })
            }
          }
        }
      }
    }