1
votes

I'm currently working on react native project.

I'm getting data with axios in componentDidMount function, but data is SOAP way. Therefore I'm changing the data xml to json with xml-js package.

Here is my state;

state = {
    contacts: [],
    isLoading: true
} 

Here is my componentDidMount() function;

componentDidMount() {
    xmls = 'my envelope to server.';
    Axios.post('my url goes here.', xmls, {
        headers: {
            'Content-Type': 'text/xml; charset=UTF-8',
            'Authorization': 'my key',
            'SOAPAction': "my action"
        }
    }).then(response => {
        return response.data;
    }).then((res) => {
        const options = {
            compact: true,
            ignoreDeclaration: true,
            spaces: 4,
            ignoreAttributes: true,
            textFn: this.removeJsonTextAttribute,
            elementNameFn: function (val) { return val.replace('SOAP-ENV:', '').replace('ns:', ''); } //removes 'SOAP-ENV: and ns: tags from SOAP data.
        }
        // converting string xml to string json.
        let xmlToJSON = convert.xml2json(res, options);
        // converting string to json with JSON.parse()
        return contactsObj = JSON.parse(xmlToJSON);
    }).then((fin) =>{
        this.setState({contacts: fin, isLoading: false});
    }).catch(err => {
        console.warn('Error', err);
    });
}

Here is my render function;

render() {
    let arr = [];
    arr.push(this.state.contacts);

    let {isLoading} = this.state;


    let res = arr.map((item, i)=> {
        return <AnnounceList headLine = {item[0].Envelope.Body.a.b.c[i]} />
     });

    return (
        <View style = {{flex: 1}}>
            <TopBar name={"Iletisim"} bColor={"#29303c"} miniLogo={require('../../../assets/pictures/Ikon07-tip2-0.png')} />
            <Spinner loading = {isLoading} color = '#29303c'>
                <ScrollView>
                {res}                      
                </ScrollView>
            </Spinner>
        </View>
    );
}

For rendering my data I'm creating an array instance and push my state contacts data to there. But when I'm trying to select data from array it is throwing me undefined is not an object error. Data is valid until Envelope but after Envelope.Body it throws an error. I didn't understand why it is throwing? Any idea. Thanks for all contribution.

Added Information!!

In my state, contacts is an array. but in my render function when I try to this.state.contacts.map() it throws me undefined is not function so I checked out what is type of it with console.log(typeof this.state.contacts) it returns object. Why did it become an object? Mustn't it stay as an array?

1
try and log the value of this.state.contacts in render method and you might figure our what actually is wrong - Shubham Khatri
@ShubhamKhatri when I console.log(this.state.contacts) I can see the all data fetched from server but when I try to this.state.contacts.map it is throwing undefined is not a function error. - tron
any solution offer? - tron
can you check what does this expression return let xmlToJSON = convert.xml2json(res, options); I believe it is an object - Shubham Khatri
yeah, so there is your issue. map is not defined for an object. Probably you want to render a particular key from the object which is an array otherwise you want to render the object in that case you can refer stackoverflow.com/questions/43721168/… - Shubham Khatri

1 Answers

0
votes

I think the problem is here

 let res = arr.map((item, i)=> {
    return <AnnounceList headLine = {item[0].Envelope.Body.a.b.c[i]} />
 });

You are looping through all item you have and you are taking item[0]? why? Then you are taking i which is index of element. Why not to use item? Adding something like:

 let res = arr.map((item, i)=> {
    return <div>JSON.stringify(item)</div>
 });

will help you with debugging. You can also make your json more beautifull with:

return <div><pre>{JSON.stringify(item, null, 2) }</pre></div>;