有什么办法可以通过API映射以下对象

时间:2019-09-08 05:17:24

标签: javascript reactjs

我想将对象从API映射到render方法。但无法映射。

我已经尝试过

{
  Uid : "1" ,
  value : 
  {
   "genre": "Artist" ,
   ....
  }
}

及其优良之处,及其运作 但我想尝试以下操作,因为我的API包含以下对象

{
  "Uid": {
    "genre": "Artist" , 
    ....
  }
}

整个对象在Firebase数据库中如下

{
    "Uid": {
        "title": "someTitle",
        "description": "Bla Bla",
        "artistName": "Bla Bla",
        "url": "someUrl",
        "likeCount": 9,
        "time": {
            "_seconds": 1564426800,
            "_nanoseconds": 0
        },
        "genre": "someGenre"
    }
}

我的构造函数包含

constructor(props) {
    super(props);
    this.state = {
      categories: [],
      G1 : [],
      G2 : [],
      G3 : []
    }; 
}                 

随后也有componentdidmount,在for循环中,第一个对象进入网格G1,第二个进入G2,第3个进入G3,第4个进入G1,依此类推,这就是为什么我有一个for循环的原因。问题是代替this.state.categories [j],应该还有其他东西。我不知道

componentDidMount(){
    axios.get("/getArtCol").then(res => {
      const key = Object.keys(res.data);
      const value = Object.values(res.data);   
      const length = this.state.categories.length

      key.forEach((element, i ) => {
        this.state.categories.push({name: element , title:Object.values(value[i])[0], price:Object.values(value[i])[1], url:Object.values(value[i])[2], likeCount:Object.values(value[i])[3], description:Object.values(value[i])[4], artistName:Object.values(value[i])[5], genre:Object.values(value[i])[6]});
      });

      let j = 0
      for(let i = 0; i < length; i++ ) {
        //this.state.paintingKeys.push({name: element , url:value[i]});
        this.state.G1.push(this.state.categories[j])
        j++
        if  (j===length){
          break;
        }                                           
        this.state.G2.push(this.state.categories[j])
        j++
        if  (j===length){
          break;
        }
        this.state.G3.push(this.state.categories[j])
        j++
        if  (j===length){
          break;
        }
      };
      this.setState({ });    
     console.log(res.data)
     //console.log(this.state.G1)
     //console.log(this.state.G2)
     //console.log(this.state.G3)    
    }).catch(err=>{
      console.log(err)
    })

  }

我希望它的第一个对象映射到网格G1中,其次映射到G2中,第3个映射到G3中,第4个映射到G1中,依此类推

  render(){ 
    const { classes } = this.props;
    let galleryMapped1 = this.state.G1 ? (this.state.G1.map(category=>(            
      <div>
        <h6>{category.Uid.title}</h6>
        <h4>{category.Uid.price}</h4>
        <h4 >{category.Uid.genre}</h4>
        <h4 >{category.Uid.artistName}</h4>
        <h4>{category.Uid.description}</h4>
        <h4>{category.Uid.likeCount}</h4>
      </div>
    ))) : (<p>Sorry, data not fetched</p>)

    let galleryMapped2 = this.state.G2 ? (this.state.G2.map(category=>(      
      <div>
      <h6>{category.Uid.title}</h6>
      <h4>{category.Uid.price}</h4>
      <h4 >{category.Uid.genre}</h4>
      <h4 >{category.Uid.artistName}</h4>
      <h4>{category.Uid.description}</h4>
      <h4>{category.Uid.likeCount}</h4>
    </div>
    ))) : (<p>Sorry, data not fetched</p>)

    let galleryMapped3 = this.state.G3 ? (this.state.G3.map(category=>(    
      <div>
      <h6>{category.Uid.title}</h6>
      <h4>{category.Uid.price}</h4>
      <h4 >{category.Uid.genre}</h4>
      <h4 >{category.Uid.artistName}</h4>
      <h4>{category.Uid.description}</h4>
      <h4>{category.Uid.likeCount}</h4>
    </div>
    ))) : (<p>Sorry, data not fetched</p>)

    return (
      <div>
        {galleryMapped1}   
        {galleryMapped2}
        {galleryMapped3}
      </div>   

    );   
  }
}

3 个答案:

答案 0 :(得分:0)

我想你想要

root = xml.etree.ElementTree.fromstring(text)

doc = nlp(root.itertext())

,如果不是,请添加更多描述并在此处粘贴渲染方法

答案 1 :(得分:0)

由于两个对象的格式不同,您将需要更改映射内容:

对于第一个对象,成员是obj.Uid和obj.value,然后obj.value具有obj.value.genre,等等...

但是第二个对象的格式不同,它只有一个成员obj.Uid,这是一个具有更多成员的对象:obj.Uid.title,obj.Uid.description。

因此,如果要映射字段标题,描述等...,则需要引用obj.Uid,不仅是obj,而且绝对不是obj.value,因为它不是第二个对象的成员。

答案 2 :(得分:0)

假设您的数据是由某些uuid键控的相同形状的对象的集合。 Object.values返回一个可以迭代/映射/归约的值的数组,而Object.entries返回一个键-值元组的数组。

在此示例中,我使用entries方法并映射到数组,以从对象中提取uid键和三个属性,并进行构造,将这些值映射为字符串,然后将其打印出来。只是想说明映射值的变异可以是任何东西。

const dataObject = {
    "1234567890": {
        "title": "someTitle",
        "description": "Bla Bla",
        "artistName": "Bla Bla",
        "url": "someUrl",
        "likeCount": 9,
        "time": {
            "_seconds": 1564426800,
            "_nanoseconds": 0
        },
        "genre": "someGenre"
    },
    "9876543210": {
        "title": "someOtherTitle",
        "description": "Bla Bla Bla",
        "artistName": "Bla Bla Bla",
        "url": "someUrl",
        "likeCount": 2,
        "time": {
            "_seconds": 1564426900,
            "_nanoseconds": 0
        },
        "genre": "someOtherGenre"
    },
    "5432109876": {
        "title": "someOtherOtherTitle",
        "description": "Bla Bla, oops",
        "artistName": "Bla Bla, oops",
        "url": "someUrl",
        "likeCount": 1337,
        "time": {
            "_seconds": 1564423800,
            "_nanoseconds": 0
        },
        "genre": "someOtherCoolGenre"
    },
};

const mappedData = Object.entries(dataObject)
  .map(([uid, { genre, likeCount, title }]) => {
    return `${title.toUpperCase()} (liked ${likeCount} times) [uid: ${uid}] <${genre}>`;
  });

console.log(mappedData);

如果您通过异步API请求获取数据,则您的组件将类似于以下内容。异步请求通常返回承诺,因此您可以处理已解决的承诺。

class MyComponent extends Component {
  state = {
    data: null,
    error: null,
    isLoading: true,
  }

  componentDidMount() {
    asyncApiRequest(...)
      .then(response => {
        // This will be specific to the shape of the API response!!
        this.setState({ data: response.data.myDataArray });
      })
      .catch(error => {
        this.setState({ error });
      });
      .finally(() => {
        this.setState({ isLoading: false });
      });
  }

  function renderData(data) {
    return Object.entries(data)
      .map((uid, { description, genre, title }) => (
        <div>
          <h1>{title} ({uid})</h1>
          <dl>
            <dt>Genre</dt>
            <dd>{genre}</dd>
            <dt>Description</dt>
            <dd>{description}</dd>
          </dl>
        </div>
      ));
  }

  render() {
    const { data, error, isLoading } = this.state;

    if (isLoading) return <LoadingSpinner />;

    if (error) {
      return (
        <div>There was an error fetching data: ${error}</div>
      );
    }

    return data.length ?
      renderData(data)
    : (
      <div>No data to display</div>
    );
  }
}

[edit:将地址分类为三个存储区“ G1”,“ G2”和“ G3”]

为了将其分类为三个网格仓,那么您拥有的是封闭的,但是您想要遍历数据一次,然后有选择地将结果推入仓0、1、2、0、1、2,...,I从0开始对bin进行编号,因为我们可以使用索引的模块化除法来计算元素应放入的bin。我们可以这样做,因为除原始顺序外,似乎对箱号没有其他依赖性。

componentDidMount(){
  axios.get("/getArtCol").then(res => {
    const dataEntries = Object.entries(res.data);

    const G1 = [];
    const G2 = [];
    const G3 = [];

    // Map to a categories array [{ name: key, title, genre, ...}, ...]
    const categories = dataEntries.map(([key, element]) => ({
        name: key,
        ...element
      });

    // Sort into 1 of 3 grid "bins"
    for(let i = 0; i < length; i++ ) {
      if (i % 3 === 0) {
        G1.push(categories[i]);
      }
      if (i % 3 === 1) {
        G2.push(categories[i]);
      }
      if (i % 3 === 2) {
        G3.push(categories[i]);
      }
    };

    this.setState({
      categories,
      G1,
      G2,
      G3,
    });        
  }).catch(err=>{
    console.log(err)
  });
}

似乎没有在计算之外使用类别,因此版本更简洁:

componentDidMount(){
  axios.get("/getArtCol")
    .then(res => {
      const dataEntries = Object.entries(res.data);

      // Map to a categories array [{ name: key, title, genre, ...}, ...]
      // then reduce directly into the three grid bins
      const grids = dataEntries.map(([key, element], i ) => ({
          name: key,
          ...element
        })
        .reduce(({G1, G2, G3}, category, i) => {
            if (i % 3 === 0) {
              G1.push(category);
            }
            if (i % 3 === 1) {
              G1.push(category);
            }
            if (i % 3 === 2) {
              G1.push(category);
            }

            return {G1, G2, G3};
          },
          { G1: [], G2: [], G3: []}
        );

      this.setState(grids);        
    })
    .catch(err=>{
      console.log(err)
    });
  }