[英]creating D3 Word Cloud by using an array of json objects instead of reading from json file
[英]Issue using array of objects from API as JSON for d3 visualization
所以我构建了一个 API ,它返回一个这样的数组:
[{"id":1,"name":"Josh","parent":null},
{"id":2,"name":"Peter","parent":1},{"id":3,"name":"Mary","parent":2}]
我可以在我的 react 应用程序上使用它来显示表格,但现在我想将它用作 d3 图表的输入。 正因为如此,我构建了一个 function,它采用一组对象并将其转换为一个大的分层对象。
function convert(array){
var map = {};
for(var i = 0; i < array.length; i++){
var obj = array[i];
obj.children= [];
map[obj.id] = obj;
var parent = obj.parent || '-';
if(!map[parent]){
map[parent] = {
children: []
};
}
map[parent].children.push(obj);
}
return map['-'].children;
问题是,当我使用 axios.get 传递从 API 获得的内容时,它会给出一个未定义的错误,就好像它无法解析数组内的对象一样。
另一方面,如果我手动插入相同的数组:
const rawData2 = [{"id":1,"name":"Javier","parent":null},
{"id":2,"name":"Nerea","parent":1},
{"id":3,"name":"Yolo","parent":2}]
它没有问题。
我不知道还能尝试什么。 我尝试了 stringfy,使用 map 解析 json,如下所示:
var result = this.state.persons.map(person => ({id: person.id, name: person.name, parent:
person.parent}))
没有任何效果。
有什么帮助吗?
EDIT: I think the problem has something to do with the fact that JS is asynchronous so when I pass the API response to my convert function I also pass some empty arrays before I actually pass the actual arrays from the data.
如何锁定数据以避免这种情况? 对不起,我缺乏技术词汇,但我对这种语言很陌生。
Edit2:这就是我从 API 检索数据的方式:
componentWillMount() {
this._refreshAliens()
}
_refreshAliens () {
axios.get('http://localhost:8080/aliens').then((response) => {
this.setState({
aliens: response.data
})
});
然后我只是简单地做: convert(this.state.aliens) 给我错误: Can add property children to undefined.
如果我 console.log(this.state.aliens):
我得到一些 [], [] 然后 (3) [{…}, {…}, {…}] 以及正确的数据。
编辑:
render() {
let aliens = this.state.aliens.map((alien) => {
return (
<tr key={alien.id}>
<td>{alien.id}</td>
<td>{alien.name}</td>
<td>{alien.type}</td>
<td>{alien.planet}</td>
<td>{alien.parent}</td>
<td>
<Button color="success" size="sm" className="mr-2" onClick={this.editAlien.bind(this, alien.id, alien.name, alien.planet)}>Edit</Button>
<Button color="danger" size="sm" onClick={this.deleteAlien.bind(this, alien.id)}>Delete</Button>
</td>
</tr>
)
})
const { all = [] } = this.state.aliens
if (Array.isArray(all) && all.length === 0) {
return <p>Loading...</p>
}
return (
<div className="App container">
...........
编辑错误:
错误:对象作为 React 子对象无效(发现:object 键为 {id, name, type, planet, parent})。 如果您打算渲染一组子项,请改用数组。
_refreshAliens/<src/App.js:60
57 | }
58 | _refreshAliens () {
59 | axios.get('http://localhost:8080/aliens').then((response) => {
> 60 | this.setState({
| ^ 61 | aliens: response.data
62 | })
63 |
在 API 请求发生期间,aliens state 将是一个空数组。 您还需要在转换 function 中处理这种情况。 添加 null 检查以避免在这种情况下返回错误。
function convert(array = []){
var map = {};
for(var i = 0; i < array.length; i++){
var obj = array[i];
obj.children= [];
map[obj.id] = obj;
var parent = obj.parent || '-';
if(!map[parent]){
map[parent] = {
children: []
};
}
map[parent].children.push(obj);
}
return map['-'] ? map['-'].children : null;
}
编辑:如果 API 的数据可用,还要添加加载程序以避免进一步的错误,就像在您的渲染 function 中一样:
render() {
const { aliens = [] } = this.state
if (Array.isArray(aliens) && aliens.length === 0) {
return <p>Loading...</p>
}
return (
// Do your stuff...
)
}
编辑 2:确保正确地从 state 中解构外星人。 生成的代码应该是这样的:
render() {
const {aliens = []}= this.state;
if (!Array.isArray(aliens) || aliens.length === 0) {
return <p>Loading...</p>
}
return (
<div className="App container">
{
aliens.map((alien) => {
return (
<tr key={alien.id}>
<td>{alien.id}</td>
<td>{alien.name}</td>
<td>{alien.type}</td>
<td>{alien.planet}</td>
<td>{alien.parent}</td>
<td>
<Button color="success" size="sm" className="mr-2" onClick={this.editAlien.bind(this, alien.id, alien.name, alien.planet)}>Edit</Button>
<Button color="danger" size="sm" onClick={this.deleteAlien.bind(this, alien.id)}>Delete</Button>
</td>
</tr>
)
})
}
// Other stuff...
</div>
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.