Full Time Skeleton
Full Time Skeleton

Reputation: 1740

Angular Interceptor hanging

I've an interceptor which I've created with the aim of having it append a query string element to every request. To know which value to append to the query string I have to connect to a service, return an observable from that service, I then switchmap to return the HTTPRequest that the interceptor is expecting.

@Injectable()
export class PermCheckInterceptor implements HttpInterceptor {
    constructor(public userService: UserService) {}
    intercept(req: HttpRequest < any > , handler: HttpHandler): Observable < httpEvent < any >> {
        return this userService.currentUser.pipe(
        switchMap(curUser => {
                return handler.handle(reg.clone {
                    setParams: {
                        "perm": curUser.hasPerms ? 'true' : 'false'
                    }
                }));
        }
    }

Currently this code throws no errors but when running the site it just hangs, which I presume is because the interceptor is never resolving. The line:

userService.currentUser.pipe

from the code above is connecting to a service and returning an observable which is created from a Subject (using .asObservable() ).

My guess is that the observable is not yet triggered or available at the time the interceptor first runs, so it just hangs. This is a guess though.

Does anything look wrong with the code above? Is there a way to check that the observable has a value before proceeding with the interceptor or is there a better way in general of doing this?

Upvotes: 1

Views: 411

Answers (1)

RJM
RJM

Reputation: 695

So the first step would be to debug to ensure you know where the problem is. As you say, it does seem likely that userService.currentUser is not emitting a value after the interceptor subscribes.

Use your preferred debugging method after this statement switchMap(curUser => { to check that it is actually emitting and what the value is. Also check that the intercept() is getting called in the first place (I assume you have already configured that but just in case).

If I were to habit a guess, userService is using a Subject and you are emitting a value, but it is only emitting once and then by the time the interceptor subscribes the value has already been emitted and thus nothing else comes down the stream. By the looks of your code, I would probably recommend using a ReplaySubject which replays a number of previous values whenever a new subscriber is added. (Read more: https://www.learnrxjs.io/learn-rxjs/subjects/replaysubject)

So when you instantiate your subject in the user service you can do:

this.userSubject = new ReplaySubject(1);

The 1 passed to the ReplaySubject constructor dictates how many values will be replayed when a new subscriber subscribes. So when the interceptor subscribes it will immediately get the last value that was emitted.

Upvotes: 1

Related Questions