I'm trying to get XML-Data from an XML-file and want to save certain node values in a list. This is how I tried to do it:
import React from "react";
class EditFiles extends React.Component {
constructor(props) {
super(props);
this.loadXML = this.loadXML.bind(this);
}
loadXML = () => {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var xmlDoc = this.responseXML;
var y = xmlDoc.getElementsByTagName("newFile");
for(var i=0; i<y.length; i++) {
var NameArray = [y[i].getElementsByTagName("FileName")[0]];
}
const nameList = NameArray.map(name =>
<li>{name}</li>
);
}
};
xhttp.open("GET", "./FilenameList.xml", true);
xhttp.send();
}
render() {
return(
<ul>{nameList}</ul>
);
}
}
First of all, I don't know if it can even be done this way. I did find similar questions, however, the code in the answers was not explained very well and I don't want to just copy and paste some code without understanding it (also, even if I wanted to do that, I probably couldn't, since I wouldn't know what represents what.
The error I'm getting with this code is that nameList is not defined in the render function. I know that it would have to be a global function, but I do not know how to do that.
I also read this post: https://medium.com/@catquarks/making-ajax-requests-with-react-48be0285d396 and wanted to do it like in the example. But I don't quite understand it, for example, how would I get the value of certain tags?
Anyway, to sum up my goal for this question: Can I use an XMLHttpRequest the way I did and what mistakes did I make exactly?
I hope this isn't all over the place. If you need further information/explanation please let me know.
Quick Edit: the XML-file looks kinda like this:
<Files>
<newFile>
<FileName>file1</FileName>
</newFile>
<newFile>
<FileName>file2</FileName>
</newFile>
</Files>
What I would also like to note, is that the xml-file is created dynamically, therefore it's not predictable how many newFile nodes there are going to be.
You need to tell React how and when to execute the code in your loadXML function. Binding it like you did in the constructor is useless here, as bind simply changes the this keyword for the loadXML function. And actually, React comes with a set of functions you should use instead, as loadXML's purpose is to fetch data from an external source.
In your case, componentDidMount is the right place to execute the code instructions of loadXML.
A best practice is to :
state in the contructor() functionXMLHttpRequest in the componentDidMount() functionMore generally, the React Component Lifecycle is a very insightful source to understand the various functions that are executed when displaying and updating a React component. You may find this example useful too.
One your data has been loaded, then update the state of your component with the data you obtain. Updating the state (or props) of a React component automatically triggers its render() function and display your changes.
Then, in the render() function, just return the DOM elements (or React components) to display based on the component's state variable. In the following example, we download JSON data (posts) from a URL using XMLHttpRequest and return the title of each post. We tell render() to check the length of the posts array in order to know if we have posts to display.
You can run the code snippet directly, data is JSON based (not XML), but I'm sure you can adapt it to your case.
class EditFiles extends React.Component {
constructor(props) {
super(props);
this.state = {
posts: []
}
}
componentDidMount() {
var xhttp = new XMLHttpRequest();
var self = this;
xhttp.onreadystatechange = function(e){
console.log(this);
if (xhttp.readyState === 4 && xhttp.status === 200){
console.log("ok, response :", this.response);
self.setState({
posts: JSON.parse(this.response)
});
}
}
xhttp.open("get", "https://jsonplaceholder.typicode.com/posts", true);
xhttp.send();
}
render() {
let postsLoaded = this.state.posts.length > 0;
return(
postsLoaded ?
<ul>
{
this.state.posts.map(
post => {
return <li>{ post.title }</li>;
})
}
</ul>
:
<div>Loading...</div>
);
}
}
ReactDOM.render(
<EditFiles />,
document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With