I have a nextjs app using typescript and a Strapi backend with graphql
I'm trying to simple get the graphql from strapi and display it in the react app.
I'm trying to display a list of font names.
In react I have this query, this works in the playground
import { gql } from "@/node_modules/@apollo/client/core/index";
export const FONT_DATA = gql`
query font_data{
fonts{
data{
attributes{
font_name
}
}
}
}
`
I'm generating types using codegen.
export type Font = {
__typename?: 'Font';
createdAt?: Maybe<Scalars['DateTime']['output']>;
font_name?: Maybe<Scalars['String']['output']>;
publishedAt?: Maybe<Scalars['DateTime']['output']>;
updatedAt?: Maybe<Scalars['DateTime']['output']>;
};
export type FontEntity = {
__typename?: 'FontEntity';
attributes?: Maybe<Font>;
id?: Maybe<Scalars['ID']['output']>;
};
export type FontEntityResponse = {
__typename?: 'FontEntityResponse';
data?: Maybe<FontEntity>;
};
export type FontEntityResponseCollection = {
__typename?: 'FontEntityResponseCollection';
data: Array<FontEntity>;
meta: ResponseCollectionMeta;
};
export type FontFiltersInput = {
and?: InputMaybe<Array<InputMaybe<FontFiltersInput>>>;
createdAt?: InputMaybe<DateTimeFilterInput>;
font_name?: InputMaybe<StringFilterInput>;
id?: InputMaybe<IdFilterInput>;
not?: InputMaybe<FontFiltersInput>;
or?: InputMaybe<Array<InputMaybe<FontFiltersInput>>>;
publishedAt?: InputMaybe<DateTimeFilterInput>;
updatedAt?: InputMaybe<DateTimeFilterInput>;
};
export type FontInput = {
font_name?: InputMaybe<Scalars['String']['input']>;
publishedAt?: InputMaybe<Scalars['DateTime']['input']>;
};
In react I have a simple page where I am calling the query and trying to display the font names
'use client'
import { getDataFromTree } from '@apollo/client/react/ssr'
import withApollo from '../lib/withApollo'
import { FontEntity, FontEntityResponse, FontEntityResponseCollection} from '@/generated'
import { useQuery } from '@apollo/client'
import { FONT_DATA } from '@/graphql/queries'
const Home = () => {
// const data: FontEntityResponse = useThemeContext()?.data;
const {data, loading} = useQuery<FontEntityResponse, FontEntity>(FONT_DATA)
if(loading || !data) return <div>Loading</div>
console.log(Array.isArray(data))
return (
<div>
<ul>
{data?.data?.attributes?.map((font:FontEntity) => (
<li key={font.id}>{font?.font_name}</li>
))}
</ul>
</div>
);
}
export default withApollo(Home, { getDataFromTree });
The map errors with Property 'map' does not exist on type 'Font'
which is because its not an array.
The console.log also says its not an array.
The graphql returns an object but how do I use that with the map, or am I using the wrong type.
Update
if I do console.log(JSON.stringify(data, null, 2))
I get
{
"fonts": {
"__typename": "FontEntityResponseCollection",
"data": [
{
"__typename": "FontEntity",
"attributes": {
"__typename": "Font",
"font_name": "Black"
}
},
{
"__typename": "FontEntity",
"attributes": {
"__typename": "Font",
"font_name": "Jasper"
}
},
{
"__typename": "FontEntity",
"attributes": {
"__typename": "Font",
"font_name": "Varly"
}
},
{
"__typename": "FontEntity",
"attributes": {
"__typename": "Font",
"font_name": "Brother"
}
}
]
}
}