cosmicjs / cosmic-sdk-js

The official JavaScript SDK for Cosmic. Use it to power content server-side, in the browser, and in native apps.
https://www.npmjs.com/package/@cosmicjs/sdk
MIT License
14 stars 2 forks source link

Incorrect documentation on how to access metadata fields #30

Closed joshuabradley012 closed 1 year ago

joshuabradley012 commented 1 year ago

The documentation for querying objects using nested metadata fields is not correct.

https://www.cosmicjs.com/docs/api/queries#advanced-examples

The documentation shows examples where the query includes metadata fields, like this:

const query = {
  type: 'products',
  'metadata.price': {
    $lt: 100,
  },
};
await cosmic.objects.find(query);

I had to write my query without the metadata prefix for it to work. However, I am also using the findOne method instead of find. Maybe that is why the interface is different than what is documented?

const query = {
  type: 'products',
  'price': {
    $lt: 100,
  },
};
await cosmic.objects.findOne(query);

Here is the full code I am using in my project.

import { PageTypes, LandingPageType } from '@/types/cosmic'; // these are internal types, we are not overriding cosmic
import { createBucketClient } from '@cosmicjs/sdk';
import config from '@/types/config';

const cosmic = createBucketClient({
  bucketSlug: config.COSMIC_SLUG,
  readKey: config.COSMIC_READ_KEY,
});

const getObjectByQuery = async (query: any) => {
  return await cosmic.objects.findOne(query).props([
    'id',
    'slug',
    'title',
    'metadata',
    'thumbnail',
    'published_at',
  ]).depth(1000);
};

const getLandingPage = async (slug: string, pageType?: LandingPageType): Promise<any> {
  const query = {
    slug,
    type: PageTypes.LandingPages,
    'page_type.key': pageType, // this is a metadata field
  };
  return getObjectByQuery(query);
},
tonyspiro commented 1 year ago

Thank you for the report. It appears that there are 2 things here:

  1. Sending the query without metadata should not work. I suspect you may be getting a false positive and it may not be sending an error.
  2. What is the page_type metafield? If it is a Select Dropdown, you will need to use the value of the response. For example "metadata.page_type": "Landing Page".

Try this and let me know if it works.

joshuabradley012 commented 1 year ago
  1. You were right that we were getting a false positive
  2. Weirdly, the example you send did not work, but this is what worked: "metadata.page_type.value": "Landing Page"
tonyspiro commented 1 year ago

Ok, it seems that it may not be using anything after "metadata.page_type". So the correct way is to do "metadata.page_type" which should work. Let me know if you have any other trouble with this, otherwise I'm going to close this issue.

joshuabradley012 commented 1 year ago

Sorry, "meta.page_type" does not work. It causes a 404 error. But "metadata.page_type.value" works perfectly. I validated that it is filtering for objects correctly.

tonyspiro commented 1 year ago

"metadata.page_type.value"

You don't need the .value. Try "metadata.page_type.anything.here" it will work also. It should just be "metadata.page_type" For example:

 const { object } = await cosmic.objects
  .findOne({
    type: "landing-pages",
    "metadata.page_type": "Landing Page",
  })
  .props("slug,title,metadata.page_type")
joshuabradley012 commented 1 year ago

I see, okay yes that is working, thank you!