简体   繁体   中英

how to map objects in javascript/ reactjs and use its key and values sepreately

i am trying to use data from an object that made by merging two arrays after making an object i am stuck at the part of how to map that object?

this is the javascript:-

 class CampaignIndex extends Component { static async getInitialProps() { const campaigns = await factory.methods.getDeployedCampaigns().call(); //first array of dataset const data = await factory.methods.getDeployeddata().call(); //2nd array of dataset const sum = [ { description: data, location: campaigns, }, ]; var result = Object.assign.apply( {}, campaigns.map((v, i) => ({ [v]: data[i] })) );// merged them into one object console.log(result); // { // '0x0B1B7F35442bC8b122B612872e63860246Ae070F': 'this is a test', // '0xB8364AE9ce43D1136CbB74321302B3738b64452D': 'hope this works', // '0xD3E37a011d4c00109341D1de06659214e77c3695': 'hi' // } //console.log(data); //console.log(campaigns); return { campaigns, data, result, }; } renderCampaigns() { const { data, beta } = this.props; const items = result.map((term) => { return { header: term.key(), meta: term.values(), description: ( <Link as={`/campaigns/${term.values()}`} // href={{ // pathname: `/campaigns/show/`, // query: { address }, // }} > <a>view campaign</a> </Link> ), fluid: true, }; }); return <Card.Group items={items} />; }

the only way it kinda worked but not correctly the only way i know was by using two arrays but it showed all of the description in one single line cause i was only able to map the address

 class CampaignIndex extends Component { static async getInitialProps() { const campaigns = await factory.methods.getDeployedCampaigns().call(); const data = await factory.methods.getDeployeddata().call(); const beta = data.map((description) => <h3>{description}</h3>); const sum = [ { description: data, location: campaigns, }, ]; console.log(data); console.log(campaigns); return { campaigns, data, beta, }; } renderCampaigns() { const { data, beta } = this.props; //const betas = data.map(description); const items = this.props.campaigns.map((address) => { return { header: data, meta: address, description: ( <Link as={`/campaigns/${address}`} href={{ pathname: `/campaigns/show/`, query: { address }, }} > <a>view campaign</a> </Link> ), fluid: true, }; }); return <Card.Group items={items} />;
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

在此处输入图像描述

{ '0x0B1B7F35442bC8b122B612872e63860246Ae070F': 'this is a test', //the key is the address '0xB8364AE9ce43D1136CbB74321302B3738b64452D': 'hope this works', //the value is the description '0xD3E37a011d4c00109341D1de06659214e77c3695': 'hi' }

i want to render it in such a way that for every address it should create a new card group which i did from the code above but i could not insert the description in the same way cause if i map it out side the render it showed all the description in the same card unlike the addresses. pls help!!

There are a couple of ways to loop through an object's properties. You can use a couple of methods: Object.keys() and Object.entries() are the most appropriate for your case.

  • Object.keys(obj) receives an object ( obj ) and returns an array of the object's keys . This way you can do Object.keys(obj).map(key => { ... }) , you already have the key , and to get the value of it, you can simply do obj[key] .

  • Object.entries(obj) is very similar to Object.keys , but returns an array of arrays, each of these arrays is composed of the key and its value ( [key, value] ). So you can do Object.entries(entry => { ... }) , and to access the entry's key: entry[0] . Same thing for the entry's value: entry[1] .

Personally, I prefer to use Object.keys because it doesn't use the indexes to access the keys and values, but both should work.

I believe your code would look like this:

renderCampaigns() {
    const { data, beta } = this.props;

    const items = Object.keys(result).map((key) => {
      return {
        header: key,
        meta: result[key],
        description: (
          <Link
            as={`/campaigns/${result[key]}`}
            // href={{
            //   pathname: `/campaigns/show/`,
            //   query: { address },
            // }}
          >
            <a>view campaign</a>
          </Link>
        ),
        fluid: true,
      };
    });
    return <Card.Group items={items} />;
  }

First of all, provide you a quick answer but it's not a good one:

        const items = this.props.campaigns.map((address, index) => {
          return {
            header: data?.[index],
            meta: address,
            description: (
              <Link
                as={`/campaigns/${address}`}
                href={{
                  pathname: `/campaigns/show/`,
                  query: { address },
                }}
              >
                <a>view campaign</a>
              </Link>
            ),
            fluid: true,
          };
        });
        return <Card.Group items={items} />;

Bellow provides you with another refactor version for your reference.

It's always better to handle data first for better-maintaining purposes.

So if the order and indexing of 2 arrays are equal, you should ask API developers to combine data together in one single API.

If they're not able to do that, then we could use promise all to combine data together at the beginning.

Let me use React hook to represent it since it's convenient to write and the performance is better.


import React, { useEffect, useState } from 'react';
import Card from 'ooo'

function getCampaigns() {
    const getDeployedCampaignApiUrl = 'https://jsonplaceholder.typicode.com/todos/2'
    const getDeployedDataApiUrl = 'https://jsonplaceholder.typicode.com/todos/3'

    const urls = [getDeployedCampaignApiUrl,
        getDeployedDataApiUrl]
  
  return Promise.all(urls.map(url => fetch(url)
    .then(response => response.json())
    .then(responseBody => responseBody.list)))
    .then(lists => {
      const result =
        lists[0].map((item, i) => Object.assign({}, item, lists[1][i]));
    })
    .catch(err => {
      console.error('Failed to fetch one or more of these URLs:');
      console.error(err);
    });
}

function Campaign() {
  const [list, setList] = useState([]);

  useEffect(() => {
    let mounted = true;
    getCampaigns()
      .then(items => {
        if(mounted) {
          setList(items)
        }
      })
    return () => mounted = false;
  }, [])

  return (
        <>
       {list.map(item => <Card.Group key={item.id} item={Object.assign({}, item, {
           description: (
            <Link
                as={`/campaigns/${item.id}`}
                // href={{
                //   pathname: `/campaigns/show/`,
                //   query: { item.address },
                // }}
            >
                <a>{item.header}</a>
          </Link>
           )
       })} />)}
     </>  )
}

export default Compaign;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM