Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gatsby - fetching remote images with createRemoteFileNode

Tags:

graphql

gatsby

I've been trying to fetch images from remote URL to Gatsby Source File system, to take advantage of lazy loading with gatsby-image plugin. I have a restful API which returns json with a string containing the image url. I followed this guide as I'm quite new to Gatsby Node Api and wasn't sure how to tackle this. Everything worked well until the point with adding additional properties to image with createNodeField. The properties seem to be added (I can see the object with fields property when I log the fileNode to the console. However, when trying to query the images, I get an error:

enter image description here

I'm wondering if there's something wrong in my code or is it due to the changes in gatsby? I'm using gatsby version 2.0.2. Is there a better option to somehow add additional properties to the image in order to be able to query just the needed ones?

Here's how my gatsby.node.js looks like:

const axios = require('axios');
const { createRemoteFileNode } = require(`gatsby-source-filesystem`);
    
exports.sourceNodes = ({ actions, createNodeId, node, store, cache } => {
  const { createNode, createNodeField } = actions;
  const processProject = project => {
    project.photos.forEach(async photo => {
      let fileNode;

      try {
        fileNode = await createRemoteFileNode({
          url: photo.photo.url,
          store,
          cache,
          createNode,
          createNodeId: id => `projectPhoto-${photo.id}`,
        });

        await createNodeField({
          node: fileNode,
          name: 'ProjectPhoto',
          value: 'true',
        });

        await createNodeField({
          node: fileNode,
          name: 'created_at',
          value: photo.created_at,
        });
      } catch (error) {
        console.warn('error creating node', error);
      }
    });
  }
  
  return axios.get(baseApiUrl).then(res => {
    res.data.forEach(project => {
      const nodeData = processProject(project);
      createNode(nodeData);
    });
  });
}
like image 303
Jan Cziżikow Avatar asked Jan 02 '23 18:01

Jan Cziżikow


1 Answers

In the end it seems that using .forEach with async/await was messing stuff up for some reason. Doing everything in for of loop, fixed the problem, although eslint was complaining about that a lot. Here's the code:

const axios = require('axios');
const { createRemoteFileNode } = require(`gatsby-source-filesystem`);

exports.sourceNodes = ({ actions, createNodeId, node, store, cache } => {
  const { createNode, createNodeField } = actions;
  const processProject = project => {
    for (const photo of project.photos) {
      let fileNode;

      try {
        fileNode = await createRemoteFileNode({
          url: photo.photo.url,
          store,
          cache,
          createNode,
          createNodeId: id => `projectPhoto-${photo.id}`,
        });

        await createNodeField({
          node: fileNode,
          name: 'ProjectPhoto',
          value: 'true',
        });

        await createNodeField({
          node: fileNode,
          name: 'created_at',
          value: photo.created_at,
        });
      } catch (error) {
        console.warn('error creating node', error);
      }
    }
  }

  return axios.get(baseApiUrl).then(res => {
    res.data.forEach(project => {
       const nodeData = processProject(project);
       createNode(nodeData);
    });
  });
}
like image 124
Jan Cziżikow Avatar answered Jan 05 '23 16:01

Jan Cziżikow