Cannot read property of undefined - Custom Post Type

Hi there,

I’m finding some weird behaviour when trying to get content from a Custom Post Type (case_studies). When I start the site with npx frontity dev I get a “Cannot read property of 89” where 89 is the ID of the post type. If I run in the console frontity.state.source and then refresh the page, it loads fine and no more error shows.

It might be that the post type has not been fetched yet and the ID is not ready.

I have added the post type under postTypes in frontity.settings.js

"state": {
        "source": {
          "url": "http://wwt.local",
          "homepage": "/home",
          "postTypes": [
            {
              "type": "case_studies",
              "endpoint": "case_studies",
              "archive": "/case_studies"
            }
          ]
        },
      }

Then I get the data in a component like this

const caseStudies = content.case_studies;
{caseStudies && caseStudies.map((caseStudy, index) => {
    const caseStudyType = caseStudy.post_type;

    useEffect(() => {
        actions.source.fetch("/case_studies");
        state.source.get("/case_studies/");
    }, []);

    const caseStudyData = state.source[caseStudyType][caseStudy.ID]; <--- here is where it breaks
    const title = caseStudyData.title.rendered;
    const client = caseStudyData.acf.client;
    const link = libraries.source.normalize(caseStudyData.link);

    return (
        <CaseStudy key={index}>
            <CaseStudyInner>
                <CaseStudyClient><b>{client}</b></CaseStudyClient>
                <Link link={link}><CaseStudyTitle>{title}</CaseStudyTitle></Link>
            </CaseStudyInner>
        </CaseStudy>
    );

})}

I’m pretty new to React and Frontity, any help would be really appreciated…! Thank you

Hi @jeffceriello

If you’ve defined the post type in frontity.settings.js then you shouldn’t need to use useEffect and actions.source.fetch() in order to get the posts. Just providing a link to the archive address should load the posts of that post type.

See this example project which demonstrates using custom post types in a Frontity project.

If you still need more help after studying the example project then please provide a link to a repo. See here for the info that you can provide that will help us to best help you.

Hi @mburridge,

Thank you so much for your reply. I’ve had a look at the repo and I tried to figure out what’s wrong with my code but with no success.

The way for it to work for me is to have the actions.source.fetch(/case_studies/) in the theme’s beforeSSR function, like so

actions: {
    theme: {
      beforeSSR: async ({ state, actions }) => {
        await Promise.all([
          await actions.source.fetch(`/case_studies/`)
        ]);
      }
    }
  },

This now works but I’m not sure if that’s how the post types are intended to work?

This is the file where I need to pull onto two case studies selected from a Post Object ACF on the Homepage

Many thanks for your support with Frontity!!

Cheers,
Jeff

Hi @jeffceriello

Thanks for providing the repo. Because you’re working with CPTs we can’t use one of our demo WordPress installations, so it would be useful for us if your WordPress site (or a version with the CPT) was also publicly available. Thanks.

Hi @mburridge

Thank you for looking into this. I’ve just managed to create a repo for the WP site, here is a link to where the CPT is created

Thanks a lot.
Jeff

Hi @jeffceriello

It looks like you haven’t created a custom taxonomy (CT) for the case_studies CPT, so Frontity doesn’t know what to use for the archive pages.

See the README file here which includes the PHP code for the CPT and CT used in the example project.

The name you give to the CT is what you assign to source.postTypes.archive. See lines 57 - 69 here.

Hope this helps.

1 Like

Hi @mburridge

Thank you for your reply. Do I have to create a taxonomy even if I don’t use it?

Sorry if I’ve misunderstood how it works…!

Thanks,
Jeff

Hi @jeffceriello

Actually, on second thoughts, no you shouldn’t have to create a taxonomy. If you look at the example we use in our step-by-step tutorial, although it has a taxonomy, it’s not being used as the value of the archive property.

Try adding the postTypes settings from your original post to the frontity.settings.js of a new project using mars-theme. Does it work then, or do you still have the same problem there?

Hi @mburridge

I’ve just tested the postTypes on the mars-theme but without the await actions.source.fetch(/case_studies/) in the theme’s beforeSSR it breaks and throws the error Cannot read property '89' of undefined

I have created a repo here frontity-post-types-test/packages/mars-theme at main · jeffceriello/frontity-post-types-test · GitHub

Could there be future issues if I keep the await actions.source.fetch(/case_studies/) in the beforeSSR function?

Thanks

Hi @jeffceriello

What happens if you use the slug of the post instead of the ID? Frontity works with URLs so unless you have a specific use case use the permalinks rather than the IDs.

Also what happens if you use the /case_studies endpoint, so if you put https://yourdomain.com/case_studies into your address bar? Do you get a listing of the case_studies post type?

In particular try this without any changes to mars-theme apart from adding the post type info to frontity.settings.js.

Again I refer you to this page in the step-by-step tutorial. That should be all you need to do to get basic functionality for CPTs, and you can extend and/or elaborate from there.

Hi @mburridge

If I append /case_studies to my url I do get a List page.

When you say I should use the slug instead of the ID, how exactly can I do that?

I am retrieving each case study with the state.source call like so

const caseStudyData = state.source[caseStudyType][caseStudy.ID];

because the case_studies array key is the ID of the case study post

Screenshot 2021-04-07 at 11.25.42

Is there any other way to retrieve each post type?

Will I eventually incur in some issues if I keep the await actions.source.fetch(/case_studies/) in the beforeSSR action in my theme? With that in it seems to be working fine.

Thanks

In JavaScript almost everything is an object, null and undefined are exceptions. This error occurs when a property is read or a function is called on an undefined variable. Undefined means that a variable has been declared but has not been assigned a value. In JavaScript, properties and functions can only belong to objects. Since undefined is not an object type, calling a function or a property on such a variable causes the TypeError: Cannot read property of undefined.

If you are not sure a variable that will always have some value, the best practice is to check the value of variables for null or undefined before using them. To avoid getting these types of errors, you need to make sure that the variables you are trying to read do have the correct value. This can be done in various ways. You can do if checks before dealing with objects whose values are bound to change:

if (myVar !== undefined) {
    ...
}

Or

if (typeof(myVar) !== 'undefined') {
    ...
}