0

I did an example of multi async XMLHttpReqest based on examples i found:

var  URL=["https://api.github.com/users/github","https://api.github.com/users/github/repos"];
var xhr = [null, null];
for (var i = 0; i < 2; i++) {
  (function(i) {
xhr[i] = new XMLHttpRequest();
xhr[i].open("GET", URL[i], true);
xhr[i].onload = function (e) {
  if (xhr[i].readyState === 4) {
    if (xhr[i].status === 200) {
      console.log(xhr[i].responseText);
    } else {
      console.error(xhr[i].statusText);
    }
  }
};
xhr[i].onerror = function (e) {
  console.error(xhr[i].statusText);
};
xhr[i].send(null);
  })(i);
}

Thing is that i am having a problem with implementing it in react as i can not assign value with this.setState({json_objs[i]:JSON.parse(xhr[i].responseText}) to object array.

This is my react code which is not working due problems with assigning value:

import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';




class ImageViewer extends React.Component {
    constructor() {
        super();
        this.state = {
            json_objs : [null,null],
            links:["https://api.github.com/users/github/repos","https://api.github.com/users/github"]
			
        }
    }
	componentDidMount() {
    var xhr = [null, null]
    for (var i = 0; i < 2; i++) {
    (function(i) {
		xhr[i] = new XMLHttpRequest();
		xhr[i].open("GET", this.state.link, true);
		xhr[i].onload = function (e) {
			if (xhr[i].readyState === 4) {
				if (xhr[i].status === 200) {
					this.setState({ json_objs[i]:JSON.parse(xhr[i].responseText)});
				} else {
				console.error(xhr[i].statusText);
				}
			}
		}.bind(this);
		xhr[i].onerror = function (e) {
		console.error(xhr[i].statusText);
		};
		xhr[i].send(null);
      })(i);
}

		 render() {
           if (!this.state.json_objs[0] || !this.state.json_objs[1]) {
				return <div>Loading...</div>;
		}
		return(
<div>
<div><h1>{this.state.json_objs[1].email}</h1></div>
				   {this.state.json_objs[0].sort(function(a, b){var keyA = new Date(a.updated_at),keyB = new Date(b.updated_at);if(keyA > keyB) return -1;if(keyA < keyB) return 1;return 0;}).map((obj, index)  => {
                            return (
								 <div key={index}>
									<div>{obj.name}</div>
									<div>{(new Date(obj.updated_at)).toString()}</td>
								</div>
                            )
                    })}
</div>
    )
}}
ReactDOM.render(<ImageViewer />, document.getElementById('root'));
<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="root"></div>

I have been reading about modyfing arrays in react but i am having problems with implementing it.

14
  • { json_objs[i]:JSON.parse(xhr[i].responseText)} is not valid javascript syntax, I expect you get some error in the console about this? Commented Aug 21, 2017 at 0:37
  • yes, i am getting errors due this. It was just to show what i am trying to do. Commented Aug 21, 2017 at 0:38
  • 1
    AHH!!! I see what you're trying to do ... you're trying to populate json_objs[i] with the result Commented Aug 21, 2017 at 0:45
  • 1
    Why not simply use axios? Commented Aug 21, 2017 at 0:50
  • 1
    Rob's answer is good then :p Commented Aug 21, 2017 at 0:54

1 Answer 1

2

I think Promise's would be helpful here. Wrap each XHR request in a Promise, use Promise.all() to wait for both of them complete, then set your results into state (it will resolve with an array of response objects):

Promise.all([0, 1].map((index) => {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest()
    xhr.open("GET", this.state.links[index], true)
    xhr.onload = function() {
      if (xhr.readyState === 4) {
        if(xhr.status === 200) {
          resolve(JSON.parse(xhr.responseText))
        } else {
          reject(xhr.statusText)
        }
    }
  })
})).then((json_objs) => {
  this.setState({ json_objs }, () => {
     console.log('json_objs => ', this.state.json_objs)
  })
}).catch(err => console.error(err))
Sign up to request clarification or add additional context in comments.

7 Comments

How do you load second link?
The code I posted makes two requests, you could use this.state.link[index] - I'll update my answer
I am wraping my head around it. Might take a sec as i am tired.
I am having highlights when i am trying to implement it.
Your render is referencing this.state.json_obj[0], that should be plural this.state.json_objs[0]
|

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.