Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

Errors when attempting `payload` access

default discord avatar
ssyberg5 months ago
4

Similar to the Cell Component post below, I'm getting this error when trying to import payload and use the api within a cell component. Seems like the proposed solution of using the REST api can't be the only way, must be missing something silly. Here's the error:



VM536:1 Uncaught TypeError: payload__WEBPACK_IMPORTED_MODULE_1__.findByID is not a function

and the code throwing it:


import React from 'react';
import payload from 'payload';
  
  
const SyndicationCell = (props) => {
    const { field, colIndex, collection, cellData, rowData } = props;
    const result = payload.findByID({
        collection: 'blogs', // required
        id: rowData.id, // required
    })
    return <span>{rowData.id}</span>;
  };
  
export default SyndicationCell;


Yea I'm in a bit of a unique situation as I'm effectively creating a separate collection to act as a traditional M2M table with additional attributes on the relationship - but for UX reasons I'd like to manage that within one end of the M2M



(So that when viewing a blog post you can see all the "sites" it's been syndicated to)



So I suppose I could expose this data with a afterRead hook and a computed prop



I'm gonna be trying to take this one step further allowing for creation of new relationships inline, perhaps with a modal



@275258786388639744

I think it'll have to be a custom component

  • discord user avatar
    dribbens
    2 years ago

    The error you're seeing is because webpack cannot handle all the backend code that comes with Payload when doing that import.


    This is not the right way for the frontend component to get the data you need.



    You have 3 options for getting data in your component.


    1) use the props on cell, which you're already doing.


    2) Use the relationship provider that wraps the table to get relational data (which looks like what you need to do)


    3) do HTTP requests using

    fetch

    or a package like

    axios

    in your component or in a custom provider.



    We haven't documented that RelationshipProvder anywhere in the docs, but this might be a good thing to add since there isn't a reason why you can't use it in your custom cell components.


    https://github.com/payloadcms/payload/blob/master/src/admin/components/views/collections/List/RelationshipProvider/index.tsx

    Note that since you're replacing the cell and normally that data is requested from the cell, you might also need to copy some parts of the relationship cell to get request the docs get loaded by the relationship provider:

    https://github.com/payloadcms/payload/blob/master/src/admin/components/views/collections/List/Cell/field-types/Relationship/index.tsx

    That is cool!



    So you effectively have a collection acting as a join table?



    I would just make another

    fetch

    request in your cell type then.



    The relationship provider won't help since it is querying with depth 0 and you would need depth 1 to get the data you're after



    @1069626017846665307

    That is expected. The relationship provider is meant to reduce duplication of requests on the list view. It is written this way so that if you have multiple columns of redundant relationships being loaded in, it can be as efficient as possible by only accessing that data once from the DB. I don't see a problem with what you have above, nice job!

  • default discord avatar
    bombnp2 years ago

    Hi,

    @778799229988110337

    . I'm also doing something similar that might require M2M relationship with additional attributes in payload (say,

    Books

    and

    Tags

    , with additional attributes)



    How do you plan on creating new relationships inline? I'm trying to find a solution but i'm not sure what's the most elegant way to do it.

  • default discord avatar
    jellygatorade2 years ago

    Necroing this thread to ask

    @969226489549713438

    if something like this would be preferred method of utilizing the

    RelationshipProvider

    in a custom

    Cell

    component.



    import { useListRelationships } from "/node_modules/payload/dist/admin/components/views/collections/List/RelationshipProvider";
    
    const ImageCell = (props) => {
      const { field, colIndex, collection, cellData, rowData } = props;
    
      const { getRelationships, documents } = useListRelationships();
    
      useEffect(() => {
        getRelationships([
          {
            value: cellData,
            relationTo: field.relationTo,
          },
        ]);
      }, [getRelationships]);
    
      return (
        <>
          {documents?.[field.relationTo]?.[cellData]?.sizes?.thumbnail?.url && (
            <img
              src={documents[field.relationTo][cellData].sizes.thumbnail.url}
              style={imageStyle}
              height={size}
              width={size}
            ></img>
          )}
        </>
      );
    };

    It looks like

    documents

    object holds returned data on all relationships in the collection type, not just the

    cellData

    passed originally into

    getRelationships()

    ? Therefore the related data I am interested in must be accessed by accessing these keys on

    documents

    ->

    documents[field.relationTo][cellData]

    ... which is not what I expected having passed that information into

    getRelationships()

    originally.



    Great! Appreciate the insight. Thanks!

  • default discord avatar
    tyteen4a03last year

    This should be in the documentation



    also, any chance this can support Suspense (as I assume payload will need to make a network request)?

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get dedicated engineering support directly from the Payload team.