简体   繁体   English

如何映射使用联合和片段在页面上呈现的graphql查询

[英]How to map graphql query which is using union and fragments to render on page

Schema: 架构:

type Link {
    items: [itemapi]      
    }

    type itemapi {
        id: ID!
        name: String!
        custom_attributes: [CUSTOM_ATTRIBUTES]
    }

    union CUSTOM_ATTRIBUTES = CustomString | CustomArray

   type CustomString {
    attribute_code: String
    value: String
  }

  type CustomArray {
    attribute_code: String
    value: [String]

  } 

  type Query {
    allLinks: Link!
  }
`;

Function: 功能:

const itemList= ({ data: {loading, error, allLinks }}) => {
  if (loading) {
    return <p>Loading ...</p>;
  }
  if (error) {
    return <p>{error.message}</p>;
  }

  return (
    <div className="itemList">
      { allLinks.items.map( aL => <div key={aL.id} className="items">{aL.???}</div> ) }
    </div>
  );
};
    const channelsListQuery = gql`
  query ChannelsListQuery {
      allLinks {
          items {
              id
              custom_attributes {
                  ... on CustomString{
                      value             
                  }
                  ... on CustomArray{
                      aliasVar: value
                  }
              }
          }
      }
  }
`;

The problem is, I don't know how to properly map this. 问题是,我不知道如何正确地映射它。 I'm using union in schema and fragments in query to get what i need and then render it on page. 我在架构中使用union,在查询中使用片段以获取所需信息,然后在页面上呈现它。 From what i know now, the query data is passed through props, so how can i get access to props in union/fragments and if possible to props that in query have aliases like value in CustomArray ? 据我所知,查询数据是通过props传递的,那么我如何才能访问联合/片段中的props,以及如果可能的话,查询中具有别名(如CustomArray value props? Because one of the value is String and second is array of strings, but with same name( value ) I needed to map it and put on one of it alias to get data from api. 因为其中一个value是String,第二个是字符串数组,但是具有相同的name( value ),所以我需要将其映射并放入其中一个别名以从api获取数据。 Do i need to use map in map function? 我需要在地图功能中使用地图吗?

{"items":[{"id":"1","custom_attributes":[{"__typename":"CustomString","value":"<p>The sporty Joust Duffle Bag can't be beat - not in the gym, not on the luggage carousel, not anywhere. Big enough to haul a basketball or soccer ball and some sneakers with plenty of room to spare, it's ideal for athletes with places to go.<p>\r\n<ul>\r\n<li>Dual top handles.</li>\r\n<li>Adjustable shoulder strap.</li>\r\n<li>Full-length zipper.</li>\r\n<li>L 29\" x W 13\" x H 11\".</li>\r\n</ul>"},{"__typename":"CustomString","value":"/m/b/mb01-blue-0.jpg"},{"__typename":"CustomString","value":"/m/b/mb01-blue-0.jpg"},{"__typename":"CustomString","value":"/m/b/mb01-blue-0.jpg"},{"__typename":"CustomString","value":"49"},{"__typename":"CustomArray"},{"__typename":"CustomString","value":"container1"},{"__typename":"CustomString","value":"0"},{"__typename":"CustomString","value":"0"},{"__typename":"CustomString","value":"0"},{"__typename":"CustomString","value":"joust-duffle-bag"},{"__typename":"CustomString","value":"0"},{"__typename":"CustomString","value":"0"},{"__typename":"CustomString","value":"0"},{"__typename":"CustomString","value":"0"},{"__typename":"CustomString","value":"0"},{"__typename":"CustomString","value":"0"},{"__typename":"CustomString","value":"0"},{"__typename":"CustomString","value":"no_selection"}],"__typename":"itemapi"},{"id":"2","custom_attributes":[{"__typename":"CustomString","value":"<p>The sporty Joust blablablablablablablablablbalbalblalbalbla not on the luggage carousel, not anywhere. Big enough to haul a basketball or soccer ball and some sneakers with plenty of room to spare, it's ideal for athletes with places to go.<p>\r\n<ul>\r\n<li>Dual top handles.</li>\r\n<li>Adjustable shoulder strap.</li>\r\n<li>Full-length zipper.</li>\r\n<li>L 29\" x W 13\" x H 11\".</li>\r\n</ul>"},{"__typename":"CustomString","value":"/m/b/mb01-blue-0.jpg"},{"__typename":"CustomString","value":"/m/b/mb01-blue-0.jpg"},{"__typename":"CustomString","value":"/m/b/mb01-blue-0.jpg"},{"__typename":"CustomString","value":"49"},{"__typename":"CustomArray"},{"__typename":"CustomString","value":"container1"},{"__typename":"CustomString","value":"0"},{"__typename":"CustomString","value":"0"},{"__typename":"CustomString","value":"0"},{"__typename":"CustomString","value":"joust-duffle-bag"},{"__typename":"CustomString","value":"0"},{"__typename":"CustomString","value":"0"},{"__typename":"CustomString","value":"0"},{"__typename":"CustomString","value":"0"},{"__typename":"CustomString","value":"0"},{"__typename":"CustomString","value":"0"},{"__typename":"CustomString","value":"0"},{"__typename":"CustomString","value":"no_selection"}],"__typename":"itemapi"}],"__typename":"Link"}

You could modify your query to include __typename . 您可以修改查询以包含__typename Assuming custom_attributes is an object: 假设custom_attributes是一个对象:

query ChannelsListQuery {
    allLinks {
        items {
            id
            custom_attributes {
                __typename
                ... on CustomString{
                    value             
                }
                ... on CustomArray{
                    aliasVar: value
                }
            }
        }
    }
}

Then inside your render function you can do something like this:
return (
  <div className="itemList">
    {
      allLinks.items.map(item => 
        <div key={item.id} className="items">
        {
          item.__typename === 'CustomString'
          ?  <div>{item.custom_attributes.value}</div>
          :  item.custom_attributes.aliasVar.map(v => <div key={v}>{v}</div>)
        }
        </div>
      )
    }
  </div>
);

Alternatively, instead of __typename , you could just check for the presence of an aliasVar property and render accordingly, but typenames are a predictable way of knowing the shape of the data you're working with. 另外, __typename ,您还可以检查是否存在aliasVar属性并相应地进行渲染,但是类型名是了解正在使用的数据形状的一种可预测的方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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