1

I am simply trying to retrieve xml data from some domain and read them onto my application. For now, I just want to read raw data. From my research, It comes to me that it is best to convert xml into json and load them onto the application. Here is what I tried to convert and print them. Could anyone advice on what I am doing wrong?

getProduction() {   
var headers = new Headers({ 'Content-Type': 'text/xml'})
headers.set('Accept', 'text/xml'); 
headers.set('Content-Type', 'text/xml');

//make the http request 
return this.http.get(this.url, {headers: headers})
                .map(res => JSON.parse(parseString(res.text(),'')))
                //Print JSON data?
                .subscribe(data =>{console.log(data);});
}

private handleErorr( error: Response){
  console.log('something went wrong');
  return Observable.throw(error.json().error || 'server error');
}
K.Son
  • 29
  • 2
  • 10
  • What is the implementation of `parseString` method? Anyway, you are using `JSON.parse()`, which needs string argument with valid JSON, so `parseString` needs to return it. Also what error are you seeing? – Martin Adámek Oct 11 '17 at 17:13

1 Answers1

1

There are 2 problems with your code:

  1. parseString() method is not synchronous, so it will not return the parsed object, you need to use callback for this.

  2. You are trying to convert the result of parseString() to JSON via JSON.parse(). That is just wrong, as the result should be already JS object. You do not need the JSON.parse() call at all.

Try it like this:

getProduction() {
    var headers = new Headers({'Content-Type': 'text/xml'})
    headers.set('Accept', 'text/xml');
    headers.set('Content-Type', 'text/xml');

    //make the http request
    return this.http
        .get(this.url, {headers})
        .subscribe(res => {
            parseString(res.text(), (err, result) => {
                if (err) {
                    return console.log('invalid XML');
                }

                console.log(result);
            })
        }, err => this.handleError(err);
}

private handleErorr(error: Response) {
    console.log('something went wrong');
    return Observable.throw(error.json().error || 'server error');
}
Martin Adámek
  • 16,771
  • 5
  • 45
  • 64
  • I tried and it shows that it cannot find the name data? – K.Son Oct 11 '17 at 18:43
  • Are you sure your API returns something? Did you check the response in chrome inspector or some rest client? Try adding `console.log(res.text());` before the `parseString` call. – Martin Adámek Oct 11 '17 at 18:48
  • Oh sorry, my bad, the variable is `result`, not data. I will update the code. – Martin Adámek Oct 11 '17 at 18:49
  • Thank you. Now I see error saying " OPTIONS http://test/Service.asmx/SendReceiveString?location=abc 403 (Forbidden)" and "Failed to load OPTIONS http://test/Service.asmx/SendReceiveString?location=abc : Response for preflight has invalid HTTP status code 403".. basically it returns handleError – K.Son Oct 11 '17 at 18:59
  • Well your API returns 403 Forbidden response, looks like its failing with OPTIONS request, sounds like there is a CORS problem (your API is served on different domain than your angular application), or maybe you are missing some token or cookie (depends on your API implementation of authentication/authorization). I can not help you with this as I am not familiar with ASP.NET, but it is a different problem that exceeds this question. You should create a new one with some more details of how your API is built. – Martin Adámek Oct 11 '17 at 19:07
  • Thanks. Btw, the original data contains a tag name at the top and closing at the very end. Is there anyway I can get rid of them? I think it's causing the parseString not working properly. – K.Son Oct 13 '17 at 14:29
  • Sure you can, `res.text()` returns plain string, you can call something like `res.text().replace(/<\/?string xmlns>/, '')` to replace them with empty string and then pass the result to `parseString`. – Martin Adámek Oct 13 '17 at 14:31
  • Hi, I just tried like I edited above. But it returns the same somehow – K.Son Oct 13 '17 at 14:38
  • Well the regexp here will depend on the exact form of these tags, also it will be case sensitive when written like this. So double check if its really just `` (every single character matters, including multiple spaces, colons, etc. You can also do string replace like this `res.text().replace('', '').replace('', '')`... – Martin Adámek Oct 13 '17 at 14:42
  • Can you please add that XML response to your question? Looks like these comments are not well suited for posting code examples. I see that you have semicolon there, that is definitely weird (that could be breaking the XML parser). `.replace('';, '') this is wrong, the semicolon needs to be part of the first string, so it should be `.replace(';', ''). But again, every single space matters here. – Martin Adámek Oct 13 '17 at 15:03