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. 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
? 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. 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
. Assuming custom_attributes
is an object:
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.
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.