skip to Main Content

i am using angular15 and here i need to generate unique id, so the process works perfectly fine, when i add set of code in that respective service file, but as that set of code is used across all service branches, i created a method under shared service and trying to get that data but i get as undefined.

shared.service.ts:

       public generateUniqueId() {
        return uuid();
       }
    
       generateCorrelationId(routerEvent:any,route:string):any {
        let previousUrl:any =[];
        let uniqueCorrelationId = '';
        routerEvent.events
        .pipe(filter(event => event instanceof NavigationEnd))
        .subscribe(({urlAfterRedirects}: NavigationEnd) => {
          previousUrl.splice(0,previousUrl.length-1)
          previousUrl = [...previousUrl, urlAfterRedirects];
          if(previousUrl.length === 1 && previousUrl[0]=== route) {
            return uniqueCorrelationId = this.generateUniqueId();
          } else if(previousUrl.length == 2 && previousUrl[1] === previousUrl[0]) {
            return uniqueCorrelationId
          } else if(previousUrl.length == 2 && previousUrl[1] != previousUrl[0]) {
            return uniqueCorrelationId = this.generateUniqueId();
          } else {
            return uniqueCorrelationId;
          }
        });
      }

component.service.ts:

    constructor(private geneateUUid:GenerateUniqueIdService) {
      let uniqueIdGeneration = this.geneateUUid.generateCorrelationId(this.router,'/findprofile');
      console.log(uniqueIdGeneration,"uniqueIdGeneration")
    }

Observation:
in Console, first component console value comes and next respective console under shared service appears.
also here based on particular component service hit, i am checking for generation of new key or retaining it, is it possible to do it dynamically i mean as a common checking whether previous and current routing is matching.

3

Answers


  1. As stated you aren’t returning anything. Personally, I would use await to make the code more readable.

    Try this:

    async generateCorrelationId(routerEvent:any,route:string): Promise<string> {
      let previousUrl:any =[];
      let uniqueCorrelationId = '';
    
      const navigationEnd: NavigationEnd = await new Promise((resolve) => {
        routerEvent.events.pipe(
          filter(event => event instanceof NavigationEnd),
          first() // wait for the first NavigationEnd event
        ).subscribe(resolve);
      });
    
      previousUrl.splice(0, previousUrl.length - 1);
      previousUrl = [...previousUrl, navigationEnd.urlAfterRedirects];
    
      if (previousUrl.length === 1 && previousUrl[0] === route) {
        uniqueCorrelationId = this.generateUniqueId();
      } else if (previousUrl.length == 2 && previousUrl[1] === previousUrl[0]) {
        // Do nothing, return empty string
      } else if (previousUrl.length == 2 && previousUrl[1] != previousUrl[0]) {
        uniqueCorrelationId = this.generateUniqueId();
      }
    
      return uniqueCorrelationId;
    }
    

    In the converted code, the generateCorrelationId function returns a Promise that resolves to the unique correlation ID. The function waits for the first NavigationEnd event using the first() operator and then uses the resolved event to get the urlAfterRedirects property.

    The splice and push methods for the previousUrl array are replaced with an assignment using the spread operator. Finally, the function returns the unique correlation ID that was generated based on the current and previous URLs.

    Login or Signup to reply.
  2. One way to go about this is to declare a Subject in shared.service.ts
    and subscribe to in the component.service.ts

    Once the logic in the routerEvent subscription is executed and the uniqueCorrelationId is finalised, then subject.next(uniqueCorrelationId) can be called and this will be read in the subscription callback block in the component.service.ts.

    Refer Code below:

    shared.service.ts:

    export class Shared {
      private uuidEmitter: Subject<string> = new Subject<string>(); 
    
      getUuidEvent(): Observable<string> {
        return this.uuidEmitter.asObservable();
      }
    
      private sendUuid(uuid: string) {
        this.uuidEmitter.next(uuid);
      }
    
     //Your Code modified
      generateCorrelationId(routerEvent:any,route:string):any {
            let previousUrl:any =[];
            let uniqueCorrelationId = '';
            routerEvent.events
            .pipe(filter(event => event instanceof NavigationEnd))
            .subscribe(({urlAfterRedirects}: NavigationEnd) => {
              previousUrl.splice(0,previousUrl.length-1)
              previousUrl = [...previousUrl, urlAfterRedirects];
              if(previousUrl.length === 1 && previousUrl[0]=== route) {
                uniqueCorrelationId = this.generateUniqueId();
              } else if(previousUrl.length == 2 && previousUrl[1] === previousUrl[0]) {
               uniqueCorrelationId = '';
              } else if(previousUrl.length == 2 && previousUrl[1] != previousUrl[0]) {
               uniqueCorrelationId = this.generateUniqueId();
              } else {
               uniqueCorrelationId = '';
              }
              this.sendUuid(uniqueCorrelationId);
            });
          }
    }
    

    component.service.ts:

    constructor(private geneateUUid:GenerateUniqueIdService) {
        this.geneateUUid.getUuidEvent().subscribe(uuid:string => {
         let uniqueIdGeneration = uuid;
         console.log(uniqueIdGeneration,"uniqueIdGeneration")
        });
             
       this.geneateUUid.generateCorrelationId(this.router,'/findprofile');     
    }
    

    Hope this helps.

    Login or Signup to reply.
  3. First of all why any ?
    The generateCorrelationId function is expected to return a value right? ‘string’ right?, but the subscribe method does not return anything. Therefore, the function will always return undefined.

    I used to commit this mistake a lot, now I generally promisify my function.

    async generateCorrelationId(routerEvent:any,route:string): Promise<string> {
      let previousUrl:any = [];
      const uniqueCorrelationId = this.generateUniqueId();
      return new Promise((resolve) => {
        routerEvent.events
          .pipe(filter(event => event instanceof NavigationEnd))
          .subscribe(({urlAfterRedirects}: NavigationEnd) => {
            previousUrl.splice(0,previousUrl.length-1)
            previousUrl = [...previousUrl, urlAfterRedirects];
            if(previousUrl.length === 1 && previousUrl[0] === route) {
              resolve(uniqueCorrelationId);
            } else if(previousUrl.length == 2 && previousUrl[1] === previousUrl[0]) {
              resolve('');
            } else if(previousUrl.length == 2 && previousUrl[1] != previousUrl[0]) {
              resolve(this.generateUniqueId());
            } else {
              resolve(uniqueCorrelationId);
            }
          });
      });
    }
    

    PS. I am not angular expert, I looked at this from a JS POV and that is all. so someone else from angular POV might have a more streamlined answer.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search