3

I cannot get the xml2js code to work so far using angular 6. I have a service.ts returning xml however when calling xml2js.parseString to convert to json I consistently get an undefined error.

"core.js:1673 ERROR TypeError: Cannot read property 'parseString' of undefined "

service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { map, filter, catchError, mergeMap } from 'rxjs/operators';
import { HttpHeaders } from '@angular/common/http';

export interface Zid {
  zpid: number;
}
const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type': 'application/x-www-form-urlencoded',
  }),
  responseType: 'text' as 'text'
};    

@Injectable({
  providedIn: 'root'
})

export class CdataServiceService {

  constructor(private _http: HttpClient) { }
  zipID = 'http://APiXml';
  getZipID() {
    return this._http.get(this.zipID, httpOptions)
    .pipe
      (map
        (res => 
          {
            return res
          }
        )
      )
  }
}

component.ts

import { Component, OnInit } from '@angular/core';
import { CdataServiceService, Zid } from '../cdata-service.service';
import { xml2js } from 'xml2js';
import { Observable, of } from 'rxjs';

@Component({
  selector: 'app-cgetter',
  templateUrl: './cgetter.component.html',
  styleUrls: ['./cgetter.component.css']
})
export class CgetterComponent implements OnInit {

  data = [];

  constructor(private cds: CdataServiceService) { }

  onKeyCompGet(event:any){
    console.log(event.target.value);
  }
  _zid :Zid

  getTheComps(){
    this.cds.getZipID()//cdataServiceService.getZipId()
    .subscribe(
      res => {
        this.convertToJson(res);
     })
  }


  public convertToJson(data: string): Object {

    let res;
    console.log(data);

    xml2js.parseString(data, { explicitArray: false }, (error, result) => {

      if (error) {
        throw new Error(error);
      } else {
        res = result;
        console.log(result);
      }

    });

    return res;

  }

  ngOnInit() {
  }

}

I have ran the returned xml to an online converter and didn't run into any problems. I have no clue on why the function returns undefined.

Also is there a way to verify all the files in xml2js is being loaded properly?

2
  • xml2js is not loaded, as the error states it is undefined. How is that referenced? Is it imported through package.json? Commented Oct 29, 2018 at 19:11
  • "xml2js": "^0.4.17" - package-lock.json this got placed there auto after running 'npm install xml2js' Commented Oct 29, 2018 at 19:22

1 Answer 1

6

Change your import in class CgetterComponent to:

import xml2js from 'xml2js';

Or:

import * as xml2js from 'xml2js';

If you examine the xml2js file which is referenced as the main file in the project's package.json. It exports an object with various properties such as Builder, Parser, and parseString, none of them have the name/identifier xml2js. So the named import you are using of import { xml2js } from 'xml2js'; is attempting to important a non-existent object property (log xml2js in the example I shared to see exported properties), hence the undefined.

Another import approach you can take, is using a named import to directly import the parseString function you are using. This would look like:

import { parseString } from 'xml2js';

And then you would simply use it as follows:

parseString(data, { explicitArray: false }, (error, result) => {
  if (error) {
    throw new Error(error);
  } else {
    res = result;
    console.log(result);
  }
});

Here is an example of the import/usage in action.

Hopefully that helps!

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks! That resolved the issue and now it's working perfectly. I now understand this alot better with how you broke it down.
Glad to help! Happy coding!
I like to highlight that parseString callback take TWO parameters, and instead of having usual result first, and error second, we have the opposite here. I kept getting null value as result, my callback looked like that e => { console.log(e); // null }.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.