0

Following roughly this answer and checking with Angular docs on header manipulation, I added the following interceptor class (as shown here).

NB. It gets invoked and other operation on the request object (like making it HTTPS etc.) work. However, the neither the added/appended nor the updated/set header seem to show.

export class CoolInterceptor implements HttpInterceptor {
  intercept(request: HttpRequest<any>, next: HttpHandler)
    : Observable<HttpEvent<any>> {

    request.headers.append("Shazoo", "Hazaa");
    request.headers.set("Content-Type", "application/text");

    console.log(request.headers);

    return next.handle(request);
  }
}

For some reason, the object displayed doesn't contain the manipulated headers. I'm getting the following.

HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, headers: Map(0)}

If I manually run append or set in the console, I see that the object changes a bit. Regrettably, it doesn't tell me anything useful that the lazyArray contains an element now nor why it doesn't contain anything while printed during the execution.

HttpHeaders {normalizedNames: Map(0), lazyUpdate: Array(1), headers: Map(0), lazyInit: HttpHeaders}

I've been reeding on this for a while and I believe I got it right, except something small misstake that I'm unable to detect or diagnose.

How do I alter the headers object of my request in the interceptor?

Or is the interceptor a poor choice of locations for such functionality, despite the docs? That wouldfollow this suggestion. I've also seen someone suggest a different approach by RequestOptions and/or by altering the this.http.get(...) parameters of the injected HttpClient, like this.

Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438
  • 1
    You cite the angular docs, *but you don't follow them*. You need to clone the request, change the clone (set the headers) and return that in the interceptor. – R. Richards Jan 31 '21 at 21:30
  • @R.Richards We are agreed regarding me not following the docs. I wasn't sure where precisely that I deviated. But now I see the double gotcha. Partly, I need to clone, just like it says. Partly, I have to manipulate the headers object according to its immutability, as suggested in the answer below. I tried both ways. Just not at the same time, hehe. Fell free to post it as an answer (or let me know so I can answer myself, although I see it as a tacky move). – Konrad Viltersten Jan 31 '21 at 22:23

1 Answers1

2

The set method on HttpHeaders doesn't mutate the object, but creates a copy. Therefore, while

    request.headers.set("Content-Type", "application/text");

won't work, [edit: request itself is immutable, therefore it needs to be cloned]

    const clonedWithRequiredHeaders = request.clone({
        setHeaders: {"Content-Type": "application/text"},
    })

should.

mbojko
  • 13,503
  • 1
  • 16
  • 26
  • I'm not sure if that will work. The field `headers` is read-only and can't be assigned. CHeck the examples I've linked to on Angular page that discuss it. – Konrad Viltersten Jan 31 '21 at 21:14
  • 2
    You should clone the request first, then you can. (request.clone) – MikeOne Jan 31 '21 at 21:27
  • @MikeOne Yes, a double-sided gotcha, that thing. Now, that I got the help, I see clearly it being stated in the docs. I was definitely right claiming that I get the point right but get stuck on a minor, idiotic mistake. My bad, entirely, hehe. – Konrad Viltersten Jan 31 '21 at 22:25
  • @mbojko Pleaes update your reply according the comments. I'll be happy to accept it as the correct answer. – Konrad Viltersten Jan 31 '21 at 22:26