Fetch CPT endpoint with params

I am trying to fetch some content from a CPT using actions.source.fetch() however I am facing some weird issues. Here is my case:

  1. I want to fetch media that has a specific parent. In my frontity settings I have this
postTypes: [
  {
    type: "product",
    endpoint: "product",
    archive: "/product",
  },
  {
    type: "media",
    endpoint: "media",
    archive: "/media",
  },
],
  1. In my Gallery component I want to fetch media that belongs to a specific parent . My code:
  useEffect(() => {
    actions.source.fetch('/media?parent=914');
  }, [])

  const data = state.source.get("/media?parent=914");

  const images = 
    data.isReady && 
    data.items.map(({ type, id }) => state.source[type][id]);

However once I do this, inside images I get basically everything from my media folder, not only the one related to the parent(914).
If I just manually go the the url in my browser site.com/wp-json/wp/v2/media?parent=914, then I see everything correctly, namely only the images with parent=914.

  1. Moreover, if I simply navigate to the browser console and type frontity.ate.source.get("/media?parent=914") i get the same response. I can basically see all media, lots and lots of entries.

So i am wondering if what I am trying to do is even possible and if yes, what am I doing wrong. I also realize that I can filter the images to get the correct ones but I don’t understand why I have to fetch 1000 images when I need 10 in that specific context.

Hopefully someone can help clarify this.

Greetings,
Nikolay

Hi @ni.bonev

media is an endpoint in the WP REST API, but it’s not a queryable path or link, and state.source.get() requires such a link or path (see docs here).

Instead you need to use libraries.source.api.get() and then libraries.source.populate(). (docs here and here).

Hopefully this will guide you to solving your problem, and you won’t need to define media as a postType in the postTypes array in Frontity.

Let us know how you get on with this.

Hi @mburridge,

that was the solution. Thanks for clarifying. Should have read the documentation better.
Here is how my final code looks. Maybe it helps someone else as well.

import React, { useEffect, useState} from 'react';
import { connect, styled } from 'frontity';
import ImageGallery from "react-image-gallery";


const Gallery = ({ productId,  state, libraries }) => {

  const [data, setData] = useState({
    isReady: false,
    items: []
  });

  useEffect(() => {
    getMedia(productId, libraries, state, setData);
  }, [])

  const images = data.isReady && data.items.map(({ type, id }) => state.source[type][id])
  let imageLinks = [];

  images && images.map(image => {
    imageLinks.push({
      original: image.media_details.sizes.medium.source_url,
      thumbnail:
        image.media_details.sizes.woocommerce_gallery_thumbnail.source_url,
    });
  });

  return (
    <GalleryWrapper>
      {imageLinks.length > 0 && (
        <ImageGallery
          items={imageLinks}
          slideDuration={0}
          showPlayButton={false}
          showFullscreenButton={false}
        />
      )}
    </GalleryWrapper>
  );
};

export default connect(Gallery)

const GalleryWrapper = styled.div`
  .image-gallery-left-nav .image-gallery-svg, .image-gallery-right-nav .image-gallery-svg {
    height: 40px;
    width: 40px;
  }
`;

const getMedia = async (parentId, libraries, state, setData) => {

  // Get other images
  const response = await libraries.source.api.get({
    endpoint: "media",
    params: {
      parent: parentId,
    },
  });
  const entitiesAdded = await libraries.source.populate({ response, state });
  await setData({
    isReady: true,
    items: entitiesAdded
  });

};
2 Likes

Awesome @ni.bonev, glad that helped you find a solution.

Hi @mburridge

const response = libraries.source.api.get({ endpoint: "media", params: {
            parent: "826",
        } });
    const entitiesAdded = libraries.source.populate({ response, state });

I am trying to get the media using the above method, but I am getting below error

(node:6756) UnhandledPromiseRejectionWarning: TypeError: response.json is not a function
    at Object.populate (webpack-internal:///./node_modules/@frontity/wp-source/src/libraries/populate.ts:35:27)

Hi @parth.nextbits

I think you need to wrap that code in an async function and then await each of the two promises.

Hope this helps.

1 Like