1

I have URL which takes three parameters like localhost:4200/website/param1/param2/pagename/param3?user=userid

If the user changes either of the parameters and its not valid , eg: localhost:4200/website/newparam1/newparam2/pagename/param3?user=userid i want to redirect them back to valid url localhost:4200/website/param1/param2/pagename/param3?user=userid

I have created the service to validate and return proper id for all these parameters. so here i am not able to replacing the param's in URL with the right value on load rather than redirect/naviagte.

I have tried to dynamically redirect in component with the below code. this.route.navigate("[relativepath,param1, param2,pagname,configid]",{queryparams})

But this will show the transition from wrong url and to the right one. i want all this to happen on load, like on resolve on route which inturn calls the service.

My service has

  createPram1(): Observable<any> {
    return of(this.parameter1);
  }

  createParam2(param1: string): Observable<any> {
    return of(this.param2);
  }

  validateParam1(id: string): Observable<any> {
    return of(this.param1=== id ? id : this.param1);
  }

  validateParam2(id: string): Observable<any> {
    return of(this.param2=== id ? id : this.param2);
  }

My Resolve.ts

export class AppPathResolve implements Resolve<any> {
  constructor(private Service: Service) { }
  resolve(route: ActivatedRouteSnapshot): Observable<any> {
     const paramOne= route.paramMap.get('param1');
     if (paramOne=== null) {
         return  this.Service.createPram1();
     } else {
         return this.Service.validateParam1(param1);
     }
  }
}

I have searched many links and i the answers dint match my requirement, finally posting it here , hoping to get some info here. thanks in advance!

Quentin
  • 1,865
  • 2
  • 24
  • 40
DpGp
  • 121
  • 1
  • 13

2 Answers2

2

If your redirected URL is not proper while redirecting, use ResponseInterceptor to intercept your request and redirect it to preferred URL.

export class ResponseInterceptor implements HttpInterceptor {

constructor() { }

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const toaster = this.injector.get(ToasterService);
    return next.handle(req)
        .map(response => {
            return response;
        }).catch(exception => {
                switch (exception.status) {
                    case '404': // you can put any status you want
                        toaster.showErrorMessage(any message to display);
                        this.router.navigate([write your preferred path location here]); // this will redirect you to specific URL
                        break;

                }
            return Observable.of(exception);
        });
}

}

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Parth Shah
  • 31
  • 1
  • sorry i have never used http interceptors , just went through it and am confused how and when and where to use it. will research more on you solution and see. – DpGp Jun 13 '19 at 07:07
  • @DpGp take a look and I am sure this code will help you to redirect your URL. – Parth Shah Jun 13 '19 at 10:10
  • can we navigate from the current path , here i need to change only the parameter of the current path and not create new on , is there any builtin function where i can get the current path and just replace the parameters with it. – DpGp Jun 13 '19 at 10:34
  • 1
    you can find current URL through this.router.url – Parth Shah Jun 13 '19 at 10:46
  • actually i used next.url[] as route.url returns "/" – DpGp Jun 14 '19 at 08:47
2

Resolvers are ideally used to fetch some data for the component before it loads. If you want to prevent a user from entering a URL use Route Guards instead.

{path: "website/:param1/:param2/pagename/:param3", component: YourComponent, canActivate: [ParamCheckGuard]}


@Injectable()
export class ParamCheckGuard implements CanActivate {

  constructor(private service: Service, private router: Router) {}

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
      const paramOne= next.paramMap.get('param1');
      if (paramOne=== null) {
          return  this.service.createPram1().pipe(map((newParam) => {
                        // form a valid URL and navigate()
                        return false
                    })
                  )
      } else {
          return this.service.validateParam1(paramOne).pipe(map((newParam) => {
                       if (paramOne == newParam) {
                          // it is a valid param.
                          return true
                       }
                       // form a valid URL and navigate()
                       return false;
                   })
                 )
      }
  }
}
Ashish Ranjan
  • 12,760
  • 5
  • 27
  • 51
  • dont want to prevent them ,consider a scenario of bookmarking the URL, when user loads the bookmarked page after long time, the specific paramter is id destroyed so in that case we will be generating a new one from the service. and wat to load the URLwith the new param that was generated. – DpGp Jun 13 '19 at 06:59
  • thanks @xyz, newUrl you have used will contain only param , for which navigateByUrl() maynot work, but this does not seem to work if the url is invalid in else case, it again blocks the current url. – DpGp Jun 13 '19 at 07:17
  • 1
    @DpGp If the URL is invalid then it will stay at the current URL (If the current URL is a valid URL then it will stay there). If you are not at the valid URL already then get the valid URL first and then navigate to it, just like I have done in the `if` block – Ashish Ranjan Jun 13 '19 at 07:27
  • jfyi, validateParam will not return boolean value , it returns a valid parameter. so in case of invalid url i need to replce current pram with valid one and navigate. so would canActivate work if i dont return true.fase after that? dont want to stay on the current url even if its invalid – DpGp Jun 13 '19 at 07:30
  • @DpGp Great, then you can use it to navigate to correct URL – Ashish Ranjan Jun 13 '19 at 07:31
  • 1
    @DpGp You can return an Object in ValidateParam1, which also contains the valid flag., if it is valid then simply return true, if not the use the parameter to navigate to correct URL. **Edit** Or esle, do a check if the returned param is same previous param then return True – Ashish Ranjan Jun 13 '19 at 07:33
  • another favour please, i dont want to use pipe , want to use observable and forgot to mentioned i tried this before with pipe and my senior dint want me to use pipe. – DpGp Jun 13 '19 at 10:38
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/194870/discussion-between-xyz-and-dpgp). – Ashish Ranjan Jun 13 '19 at 10:41