Home > Mobile >  Angular2 HttpClient get requests that respond with application/javascript are parsed as JSON but I w
Angular2 HttpClient get requests that respond with application/javascript are parsed as JSON but I w

Time:10-05

The tl;dr of my question: Is there a way to setup Angular's HttpClient to have this same behavior as it does in the jQuery and CGI example? Is there a way of using the Angular HttpClient to not interpret the response as JSON, but instead just eval(response_data)?

When running ng serve and making a request in the application using HttpClient#get, like this...

return this.httpClient.get('/assets/values.json')
return this.httpClient.get('/assets/values.js')

... the Angular development web server returns a response with an appropriate Content-Type header, of which the value for the above get requests are, respectively:

Content-Type: application/json
Content-Type: application/javascript

If I put JavaScript in the values.js file, I get a syntax error, "SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data" -- which to me is an obvious indication that the application/javascript is not being executed in the browser. It's being interpreted through the automatic execution of the JSON.parse function. The file should not be interpreted as JSON, and this is not the behavior I want.

The behavior that I want is to execute the JavaScript response, similar to what happens when a CGI server response is returned:

Content-Type: text/javascript

x=1;

If I run a web app that calls jQuery.get('/values.js'), and a CGI backend script returns the above response, then x has the value 1 in my browser's window (the JavaScript global) object. This is the (somewhat unclear behavior) of jQuery, but I am guessing it has to do with using the Content-Type header. Seemingly, jQuery#ajax is called with a dataType: "script" property on the options.

EDIT: Before you ask "why am I doing it like this? Try doing this instead..." The reason I'm using assets like this is to create an environment exactly like that which I am building this app for. The GUI app is going to run in an environment with a CGI backend, and the API Response Format described in the backend is specified. I cannot change it. I would like to design my frontend app using mock behavior so that I don't have to deploy the app every time I want to test it. The frontend application being developed using ng serve is an ideal environment because of its auto-refreshing developer experience, and to make it even more useful for me (I think) I want this behavior.

CodePudding user response:

Use a different HttpClient#get configuration object, so that Angular does not interpret the response as JSON and it will not return the return value of JSON.parse when it's configured as below:

const options = {
  observe: 'body' as const,
  responseType: 'text' as const,
};
return this.httpClient.get('/assets/values.js', options)

When the HttpClient#get returns, the value will be an Observable with the response body as a parameter of the data returned.

You can subscribe to the Observable and call eval like this .subscribe(data => eval(data)) to get the same behavior as jQuery.

  • Related