gatsby-image getting props as undefined in the component - reactjs

I'm able to get the image data in GraphiQL but can't get to work in the component. Please let me know where I'm going wrong.
import React from "react";
import { graphql } from "gatsby";
import Img from "gatsby-image"
export default function Landing({ data }) {
console.log(data) // undefined
return (
<section id="landing" className="d-flex flex-column justify-content-around">
</section >
)
}
export const query = graphql`
{
img: file(relativePath: {eq: "landing-women.jpg"}){
childImageSharp{
fluid{
src
}
}
}
}
`;

I think it has to do with your component not being in the 'pages' folder and so not being a page. Is that correct? Using page queries in components will cause the data to be undefined.
In gatsby you have page queries (for pages), and static queries (for components)

Usually, you would have a uniquely named query on each page component, otherwise I'm not sure whether Gatsby knows to extract it and pass it's resolved value as the data prop or not.
import React from "react";
import { graphql } from "gatsby";
import Img from "gatsby-image"
export default function Landing({ data }) {
console.log(data)
return (
<section id="landing" className="d-flex flex-column justify-content-around">
</section >
)
}
export const query = graphql`
query LandingQuery {
img: file(relativePath: {eq: "landing-women.jpg"}){
childImageSharp{
fluid{
src
}
}
}
}
`;

Well I don't know the exact reason behind it but, I did solve the issue by creating a seperate component for the image query and then importing it where required.
import React from "react";
import { useStaticQuery, graphql } from "gatsby"
import Img from "gatsby-image";
const Image = () => {
const data = useStaticQuery(graphql`
query {
img: file(relativePath: {eq: "landing-women.jpg"}){
childImageSharp{
fluid{
...GatsbyImageSharpFluid_tracedSVG
}
}
}
}
`)
return <Img className="img-fluid order-0 order-md-1 col-12 col-md-7"
fluid= {data.img.childImageSharp.fluid} />
}
export default Image

Related

Can't load in images from Contentful using GatsbyJS

First time posting here, but I've been struggling with this for a few days now.
Basically I have a graphQL query that pulls in product data from contentful and then display it on a GatsbyJS page. The query correctly displays for the title, price, and description of the product but it wont load in the image. Unfortunately I keep receiving errors such as:
"TypeError: Cannot read property '0' of undefined"
or
Cannot read property 'src' of undefined. (When changing the query to look at the src of an image. When I do this method, the url does have a value according to GraphiQL)
here's the code for the page I am currently working on:
import React from 'react'
import { graphql } from 'gatsby'
import Img from 'gatsby-image'
import Layout from '../components/Layout'
import './shop.scss'
const Shop = ({ data }) => {
return (
<Layout>
<section>
{data.allContentfulProducts.edges.map( ({ node }) => (
<article key={node.id}>
<Img
fluid={node.images.fluid}
/>
<p>{node.productName}</p>
</article>
))}
</section>
</Layout>
)
}
export const productQuery = graphql`
query {
allContentfulProducts {
edges {
node {
id
productName
images {
fluid {
...GatsbyContentfulFluid
}
}
}
}
}
}
`
export default Shop
I think there is a problem with you graphQL Query. Try this one:
export const productQuery = graphql`
query {
allContentfulProducts {
edges {
node {
id
productName
image {
fluid {
src
...GatsbyContentfulFluid
}
}
}
}
}
}
`
If this query is not helping please show us the structure of your contentful assets.

How do you query and display a folder of multiple images using GatsbyJS and GraphQL

I'm trying to query all images in a folder and display them in a card grid with tailwindCSS and gatsby-image. I've been able to query and display one image, but when I try to do it with a folder of images, I get the error "TypeError: Cannot read property 'edges' of undefined" even though the query works in the GraphQL explorer. I've read the docs, looked at other tutorials, and tried it so many different ways now and can't figure out what's wrong. Any help is greatly appreciated!
import React from "react";
import { graphql } from "gatsby";
import Img from "gatsby-image";
import Layout from "../components/layout";
import SEO from "../components/seo";
const ArtPage = props => (
<Layout>
<SEO
keywords={[`art`, `paint`, `draw`]}
title="Art"
/>
<div class="flex flex-wrap mt-2 mx-1">
{props.artImages.edges.map(img => (
<div class="w-full md:w-1/2 lg:w-1/2 px-2 my-2">
<div className="rounded overflow-hidden shadow-lg">
<Img
className="w-full"
fluid={img.node.childImageSharp.fluid}
/>
</div>
</div>
))}
</div>
</Layout>
)
export default ArtPage;
export const query = graphql`
query artImages {
allFile(filter: { relativePath: { regex: "/art/.*.png/" } } )
{
edges {
node {
relativePath
name
childImageSharp {
fluid(maxWidth: 500) {
...GatsbyImageSharpFluid
}
}
}
}
}
}
`;
Debugging such an issue is always difficult. Since you stated that your query is correct in GraphiQL you probably made a mistake referencing the right attributes in the GraphQL tree. undefined is an indicator that you reference an object that does not exist.
The secret weapon for debugging this issue is actually console.log(graphQlobject). Print the object in your browser and try acessing the attributes until you get it right.
I will give you my HeaderSupplier component that I use in my project and reference the important bits with comments:
import React from "react";
import { graphql, useStaticQuery } from "gatsby";
import GatsbyImage from "gatsby-image";
import styled from "styled-components";
import { pickRandomly } from "../util/utilityFunctions";
/**
* Returns one random image header.
* Uses GatsbyImage and GraphQL to load images.
* #see https://www.orangejellyfish.com/blog/a-comprehensive-guide-to-images-in-gatsby/
*/
const HeaderSupplier = () => {
const { allFile } = useStaticQuery(graphql`
query {
allFile(filter: {
extension: {regex: "/(jpg)|(jpeg)|(png)/"},
sourceInstanceName: {eq: "headers"}})
// filter by sourceInstanceName, see the gatsby-config.js,
// this way you get exactly the files you need without complicated regex statements
{
edges {
node {
childImageSharp {
fluid(maxWidth: 150, quality: 100) {
originalName
...GatsbyImageSharpFluid
}
}
}
}
}
}`);
// use console.log for debugging and correctly navigating the graphQL tree
console.log(allFile);
const header = pickRandomly(allFile.edges);
const { fluid } = header.node.childImageSharp;
// make sure you reference the correct objects
// if you get undefined you made a mistake navigating the GraphQL tree
return (
<GatsbyImage fluid={fluid} alt={fluid.originalName} />
);
};
export default HeaderSupplier;
The source instance in the gatsby-config.js:
{
resolve: "gatsby-source-filesystem",
options: {
path: `${__dirname}/src/components/library/headers`,
name: "headers",
},
I was using props.artImages instead of props.data.artImages ooooooops

Trying to Display Additional Image Thumbnails Below Main Featured Product Image

Can't get files from Moltin API to display under main product image
Using this repo: https://github.com/moltin/gatsby-demo-store and updating
#moltin/gatsby-source-moltin to 1.3.1 I have tried expanding the product
node schema to include relationships as per Moltin API documentation then
referencing this in a new component but no additional images render.
Had a look at other implementations i.e. Gatsby Store example which uses
Thumbnails and could get a tiny clickable thin purple strip rendering but with no image. The store uses Shopify and localFile storage for image rendering so this use case is not applicable.
```
import React, { useContext, useEffect, useReducer, useState } from 'react'
import { graphql, withPrefix } from 'gatsby'
import SEO from '../components/SEO'
import Photo from '../components/Photo'
import Badge from '../components/Badge'
import AddToCart from '../components/AddToCart'
import { Shopkit } from '../shopkit'
import Img from 'gatsby-image'
const {
meta: { display_price }
} = product
return (
<React.Fragment>
<SEO
type="product"
title={product.meta_title || product.name}
description={product.meta_description || product.description}
image={withPrefix(product.mainImage.childImageSharp.fixed.src)}
/>
<div className="flex flex-wrap md:bg-grey-light">
<div className="py-2 md:py-5 md:px-5 w-full lg:w-1/2">
<div className="sticky pin-t">
<Photo
src={product.mainImage}
alt={product.main_image_alt_text || product.name}
/>
<Img
src={product.relationships.files.data.id}
alt=""
/>
</div>
</div>
......
.....
....
</React.Fragment>
)
}
export const query = graphql`
query($id: String!) {
product: moltinProduct(id: { eq: $id }) {
id
slug
name
description
sku
mainImage {
childImageSharp {
fixed(width: 560) {
...GatsbyImageSharpFixed
}
}
publicURL
}
meta {
display_price {
without_tax {
formatted
}
}
}
manage_stock
meta_title
meta_description
on_sale
bulb
bulb_qty
material
finish
max_watt
relationships {
main_image {
data {
id
}
}
files {
data {
type
id
}
}
}
`
export default ProductPage
```
Would like to get small thumbnail rending below main product image. Console
error message when using Img component: Uncaught TypeError: Cannot read
property 'src' of undefined.
gatsby-source-moltin adds a images field to the product schema which you can query like so:
images {
childImageSharp {
fluid(maxWidth: 300) {
...GatsbyImageSharpFluid
}
}
}
I put together an example on CodeSandbox.

react, gatsby - how to access GraphQL query data in react class component

I've a react component named 'Header' in /src/components directory in gatsby defined as below:
import React, { Component } from "react"
import { Link } from 'gatsby'
import { StaticQuery, graphql } from 'gatsby'
import Img from "gatsby-image"
import "./header.css"
class Header extends Component {
constructor(props) {
super(props);
}
render() {
return(
<Img fixed={data.file.childImageSharp.fixed} />
)
}
}
export default Header
export const query = graphql`
query {
file(relativePath: { eq: "logo.png" }) {
childImageSharp {
# Specify the image processing specifications right in the query.
# Makes it trivial to update as your page's design changes.
fixed(width: 125, height: 125) {
base64
}
}
}
}
`
I tried to use StaticQuery with function component but it didn't work. So, I want to stick to the class component syntax.
Here, the query executes fine in http://localhost:8001/___graphql
How do I access query data in react class component ?
Only page component files can export a query variable to query like your example shows. See Use a page query in the Gatsby documentation.
Here's an example of StaticQuery usage with a class component. You have to wrap the class component with a functional component to make it work.
import React from 'react'
import { graphql, StaticQuery } from 'gatsby'
class CoolThing extends React.Component {
render () {
console.log(this.props)
return (
<div>
{this.props.site.siteMetadata.title}
{/* conditionally render directories */}
{this.props.directories.edges && (
<ul>
{this.props.directories.edges.map((directory) => {
return <li key={directory.node.id}>{ directory.node.name }</li>
})}
</ul>
)}
</div>
)
}
}
export default () => (
<StaticQuery
query={graphql`
query {
site {
siteMetadata {
title
}
}
allDirectory {
edges {
node {
id
name
}
}
}
}
`}
render={(data) => (
<CoolThing site={data.site} directories={data.allDirectory} />
)}
/>
)
Here is a related discussion on the topic.
You may also consider using Gatsby's useStaticQuery hook.

Stuck on GraphQl query in Gatsby using imageSharp

I am trying to get the following background prop set to a image in my src/images/bird.jpg directory. Here is my code, but I get a Cannot read property 'id' of undefined from my graphQl query in the console and the background prop returns null in React Inspector, What am I doing wrong?
/src/pages/index.js
import React from 'react'
import { graphql } from 'gatsby'
import Img from 'gatsby-image'
import Layout from '../components/layout'
const IndexPage = ({ data }) => (
<Layout>
<h1>Hi people</h1>
<p>{data.site.siteMetadata.title}</p>
<p>{data.site.siteMetadata.desc}</p>
<p>Welcome to your new Gatsby site.</p>
<p>Now go build something great.</p>
</Layout>
)
export default IndexPage
export const query = graphql`
query SiteMeta {
site {
siteMetadata {
title
desc
}
}
background: imageSharp(id: { regex: "/bird.jpg/" }) {
sizes(maxWidth: 1240) {
...GatsbyImageSharpSizes
}
}
}
`

Resources