Como posso usar um campo como um filtro de uma consulta graphql para obter uma imagem fluida que está em uma consulta separada?

Aug 16 2020

Eu tenho duas fontes graphql, uma para imagens fluidas e outra para caracteres em um banco de dados mongo. Estou mapeando os personagens para a página e preciso usar os nomes dos personagens (o campo de nome no "allMongodbMobileLegendsdevChamps") como um filtro (usando possivelmente o filtro originalName) para encontrar o fluido img. Então eu tenho algo assim

query MyQuery {
  allMongodbMobileLegendsdevChamps {
    nodes {
      name
    }
  }
  allImageSharp(filter: {fluid: {originalName: {eq: "characterName.jpg"}}}) {
    nodes {
      fluid {
        ...allImageSharpFluid
      }
    }
  }
}

const Index = ({ data }) => {
  const {
    allMongodbMobileLegendsdevChamps: { nodes: champs },
    allImageSharp: { nodes: fluid },
  } = data
  return (
    <section className={grid}>
      {champs.map(champ => {
        return (
          <Link to={`/champ/${champ.name}`}>
            <Image fluid={fluid.fluid} />
            <h3>{champ.name}</h3>
          </Link>
        )
      })}
    </section>
  )
}

Se eu não estivesse usando o graphql, apenas definiria o src na imagem como "champ.name" assim:

<Image src = `/path/to/img/${champ.name}.jpg` />

Como posso filtrar minha consulta de imagem com o champ.name? Devo usar o Apollo para algo assim?

Respostas

3 Saihaj Aug 27 2020 at 11:24

Isso é Gatsby e atualmente não é possível porque você não pode passar variáveis ​​para consultas que seguem esse problema do GHhttps://github.com/gatsbyjs/gatsby/issues/10482

Supondo que fosse possível passar variáveis, eu faria todos os caracteres como uma consulta de página que me permitiria reestruturar o nome a partir de props e depois uma consulta estática para a qual eu passaria o nome como filtro.

1 Peeper Aug 31 2020 at 11:56

Eu usei esta solução e adaptei um pouco para minhas necessidades: Variáveis ​​em consultas graphQL

Em um componente pai eu mapeio todos os campeões e crio um componente filho para cada um, e passo o nome dos campeões.

No componente filho, tenho uma variável, nome, que armazena o nó correto para a imagem que desejo exibir usando o método find para corresponder o nome dos campeões às imagens parentePath (as imagens têm o mesmo nome exato do campeão) . Em seguida, chamo a função renderImage que consome a variável "name" e encontra a imagem fluida em node.childImageSharp.fluid, e cria meu componente de imagem com a localização correta da imagem fluida.

import React from "react"
import { useStaticQuery, graphql } from "gatsby"
import { displayName } from "../../utils/championName"
import * as S from "../styled/ChampionGridCard"

const renderImage = file => {
  return <S.ChampionImage fluid={file.node.childImageSharp.fluid} />
}

const ChampionGridCard = props => {
  const data = useStaticQuery(graphql`
    {
      allFile(filter: { sourceInstanceName: { eq: "champImages" } }) {
        edges {
          node {
            extension
            relativePath
            childImageSharp {
              fluid {
                ...GatsbyImageSharpFluid
              }
            }
          }
        }
      }
    }
  `)

  const name = data.allFile.edges.find(
    image => image.node.relativePath === `ssbu/${props.champName}.jpg`
  )

  return (
    <S.ChampionGridCard to={`/champ/${props.champName}`}>
      <S.ChampionImageWrapper>{renderImage(name)}</S.ChampionImageWrapper>
    </S.ChampionGridCard>
  )
}

export default ChampionGridCard