¿Cómo puedo usar un campo como filtro de una consulta de graphql para obtener una imagen fluida que está en una consulta separada?

Aug 16 2020

Tengo dos fuentes de graphql, una para imágenes fluidas y otra para caracteres en una base de datos mongo. Estoy asignando los personajes a la página y necesito usar los nombres de los personajes (el campo de nombre en "allMongodbMobileLegendsdevChamps") como filtro (usando posiblemente el filtro originalName) para encontrar la imagen fluida. Entonces tengo algo como esto

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>
  )
}

Si no estuviera usando graphql, simplemente configuraría el src en la imagen en "champ.name" de esta manera:

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

¿Cómo puedo filtrar mi consulta de imagen con champ.name? ¿Debería usar Apollo para algo como esto?

Respuestas

3 Saihaj Aug 27 2020 at 11:24

Esto es Gatsby y actualmente no es posible porque no puede pasar variables a las consultas que siguen a este problema de GH.https://github.com/gatsbyjs/gatsby/issues/10482

Suponiendo que fuera posible pasar variables, haría todos los caracteres como una consulta de página que me permitirá reestructurar el nombre de los accesorios y luego una consulta estática a la que pasaría el nombre como filtro.

1 Peeper Aug 31 2020 at 11:56

Usé esta solución y la adapté ligeramente a mis necesidades: Variables en consultas de graphQL

En un componente principal mapeo todos los campeones y creo un componente secundario para cada uno, y le paso el nombre de los campeones.

En el componente secundario, tengo una variable, nombre, que almacena el nodo correcto para la imagen que quiero mostrar usando el método de búsqueda para hacer coincidir el nombre del campeón con la ruta relativa de las imágenes (las imágenes tienen exactamente el mismo nombre que el campeón) . Luego llamo a la función renderImage que consume la variable "nombre" y encuentra la imagen fluida en node.childImageSharp.fluid, y crea mi componente de imagen con la ubicación correcta de la imagen 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