angular: Dependency injection not working for custom RequestOptions class when making a post request to remote url

I’m submitting a … (check one with “x”)

[x ] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

I have a CustomRequestOptions class that extends the RequestOptions class which I want to be injected with some values from a config class that I need for customising the headers and request URL etc. This is working fine with GET requests but when I come to do a POST request I am experiencing some unexpected behaviour. The api I am calling is on a different domain so CORS browser policy is issuing a pre-flight OPTIONS request which is expected but the RequestOptions code is kicking in twice and dependency injection of the config does not work when my POST request is actually executed (the second time the RequestOptions code kicks in…

Expected/desired behavior

I am expecting to be able to dependency inject an extended RequestOptions class when making a POST request. As to whether the RequestOptions should be called twice I am unsure what the teams desired behaviour is…

Reproduction of the problem If the current behavior is a bug or you can illustrate your feature request better with an example, please provide the steps to reproduce and if possible a minimal demo of the problem via https://plnkr.co or similar (you can use this template as a starting point: http://plnkr.co/edit/tpl:AvJOMERrnz94ekVua0u5).

Reproduction is here: http://plnkr.co/edit/Bcr0RfJIf65TXOkgwgs2 see console log for outputs.

Please tell us about your environment:

  • Angular version: 2.0.0-rc.6
  • Browser: [all ]
  • Language: [ TypeScript 2.0 ]

Cross ref: http://stackoverflow.com/questions/39359060/angular2-rc6-custom-requestoption-behaviour-when-cors-post-request

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 1
  • Comments: 25 (9 by maintainers)

Most upvoted comments

Overriding merge in RequestOptions is not a supported usage of the API. There will be a much better way of manipulating request options in upcoming HTTP APIs (interceptors).

@mattheiler I am having the same issue and came to the same conclusion. How did you workaround this issue ? @DzmitryShylovich what would be the (angular) way to change an http header ?

Merge seems like it should be a utility rather than behavior. To get what I had wanted, I’d have to override merge like this:

@Injectable()
export class CustomRequestOptions extends BaseRequestOptions {

    ...

    merge(args: RequestOptionsArgs): CustomRequestOptions {

        var options = super.merge(args);

        var element = document.getElementsByTagName('base').item(0);
        if (element != null)
            options.url = element.href + (options.url || '');

        var clone = new CustomRequestOptions();
 
        // i can't return the result of super.merge(), since it is a new instance of the wrong type
        // i have to re-map everything
        // consumers shouldn't have to babysit this mapping...
        // we seem to be mixing cloning with merging

        clone.body = options.body;
        clone.headers = options.headers;
        clone.method = options.method;
        clone.responseType = options.responseType;
        clone.search = options.search;
        clone.url = options.url;
        clone.withCredentials = options.withCredentials;

        return clone;
    }

}

This issue is caused by the RequestOptions.merge() method - it creates a new instance of type RequestOptions, rather than the injected type. The Http service calls this method when merging options for the POST, PUT, and PATCH methods. IMO, either make RequestOptions follow the prototype pattern, or remove that RequestOptions.merge() and change the POST, PUT, and PATCH methods in the Http service.