angularrxjsrouterangular-routerangular-resolver

Angular Router not Resolving Promises before returning observable


I have a resolver which uses the url to fetch the parent called a bubble, for the reply that I then want to fetch based on the URL.

Problem is that my findReplyByUrl() function wont wait for the DOCID that I am trying to resolve. The resolver delivers a null observable to the component.

Does anyone know where I am going wrong here?

reply.resolver.ts

@Injectable({
    providedIn: "root"
})
export class ReplyResolver implements Resolve<Promise<Observable<Reply>>> {

    constructor(private replyModeStore: ReplyModeStore,
                private bubbleStore: BubbleStore,
                protected bubbleResolver: BubbleResolver) {

    }

    async resolve(route: ActivatedRouteSnapshot, 
            state: RouterStateSnapshot): Promise<Observable<Reply>> {
            
            const replyUrl = route.paramMap.get("replyUrl");

            const bubbleUrl = replyUrl.split("-reply-")[0];
            console.log(bubbleUrl) //It works here 
            let bubbleDocId = await this.returnBubble(bubbleUrl);
            console.log(bubbleDocId) // this is undefined
            const reply = await this.replyModeStore.findReplyByUrl(await bubbleDocId, replyUrl)     

            return await reply;
    }

    async returnBubble(bubbleUrl:string):Promise<string> {
        let bubbleUId:string;
        const bubble$ = this.bubbleStore.findBubbleByUrl(bubbleUrl);
        
        await bubble$.subscribe(res => {
            bubbleUId = res.docid
        });

        return await bubbleUId;

    }
}

reply.store.ts

    async findReplyByUrl(bubbleDocId:string, replyUrl:string):Promise<Observable<Reply>>{

        return from(this.db.collection(`vwubbles/${bubbleDocId}/replies`,
            ref => ref.where("url", "==", replyUrl))
            .get()
            .pipe(
                map(results => {

                    const replies = convertSnaps<Reply>(results);

                    return replies.length == 1 ? replies[0] : null;
                    // this.individualReplySubject.next(replyToSet);

                })
            )
        )
    }

bubbles-routing.module.ts

const routes: Routes = [
  {
    path: "",
    component: VwubblesComponent
  },
  {
    path: 'bubble/:bubbleUrl',
    component: BubbleComponent,
    resolve: {
      bubble: BubbleResolver
    }
  },
    {
      path: "reply/:replyUrl",
      component: ReplyComponent,
      resolve: {
        reply: ReplyResolver
      }
    }
];

@NgModule({
  imports: [
    RouterModule.forChild(routes)
  ],
  exports: [RouterModule],
  providers: [
    ReplyResolver,
    BubbleResolver
  ]
})
export class BubblesRoutingModule {}

Solution

  • Your problem is with returnBubble which doesn't return a Promise resolving your request.

    returnBubble(bubbleUrl: string): Promise<string> {
        return firstValueFrom(
            this.bubbleStore.findBubbleByUrl(bubbleUrl).pipe(map((res) => res.docid))
        );
    }·