Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make Angular 2 send all requests as application/x-www-form-urlencoded

I have had a similar problem with Angular 1 so I understand how to implement, only I'm missing the last step.

Just like last time, a guy who did backend for our app accepts requests with type application/x-www-form-urlencoded and just like Angular 1 so does Angular 2 send them with type application/json.

What I did with ng1 was that in config I modified the http provider to run urlencoded over body of each request.

I see in ng2 that there is https://angular.io/docs/ts/latest/api/http/BaseRequestOptions-class.html a BaseRequestOptions class which I supposed is made for exactly this only documentation is a bit not there so I'm not sure how to implement this properly (I'm also new to TypeScript).

How do I provide this so that each of my post and other requests get send as urlencoded at the end (I also want the function to be run on the body so that it actually becomes urlencoded).

Also: Why isn't there a simpler option for this since by now I can see that both ASP.Net and Flask (so I suppose many others as well) do not support application\json by default?

EDIT: I have made a custom function which I use on every object I send in POST body but I hope that there is a simpler, more general solution.

import { URLSearchParams } from 'angular2/http';

export function urlEncode(obj: Object): string {
    let urlSearchParams = new URLSearchParams();
    for (let key in obj) {
        urlSearchParams.append(key, obj[key]);
    }
    return urlSearchParams.toString();
}

and then I use it like

this.http.post('http://localhost:5000/user/auth/login', urlEncode(data))
like image 237
ditoslav Avatar asked Jan 10 '16 11:01

ditoslav


1 Answers

Try something like this:

DefaultRequestOptions.ts

@Injectable()
export class DefaultRequestOptions extends BaseRequestOptions{
    headers:Headers = new Headers({
        'Content-Type': 'application/x-www-form-urlencoded'
    });
}

boot.ts

bootstrap(AppComponent,[
    HTTP_PROVIDERS,
    provide( RequestOptions, { useClass: DefaultRequestOptions } ),
    provide(Http, { useFactory:
        function(backend, defaultOptions) {
            return new Http(backend, defaultOptions); },
        deps: [XHRBackend, RequestOptions]})
]);

IMPORTANT: Make sure you don't declare HTTP_PROVIDERS again in the component where you'll use the Http object or it'll override the one you are injecting in boot.ts.


For the other function you can just add it into any @Injectable object, add that object into the constructor of your components and you can call it that way from any component, or you can try to extend the http angular object and override the post method in order to do it for every post request behind the scenes.

like image 70
Langley Avatar answered Nov 16 '22 16:11

Langley