eleventy icon indicating copy to clipboard operation
eleventy copied to clipboard

Computed property that depends on computed property of another object doesn't work

Open monochromer opened this issue 2 years ago • 0 comments

Describe the bug I have two collections - articles and categories.

For categories i used this markdown structure:

---
title: CSS
---

All about CSS

For articles i used this markdown structure:

---
title: First Post
categories:
  - html
  - css
---

Content of post

In front-matter section of post categories are fileSlugs of corresponding category markdown file.

I want to use directory js-data files for more flexible data transforming and cleaner html templates. Data file for articles collection directory (https://github.com/monochromer/eleventy-deep-nested-computed-data/blob/main/src/articles/articles.11tydata.js):

module.exports = {
  eleventyComputed: {
    id: (data) => {
      const { fileSlug } = data.page
      return fileSlug
    },

    populatedCategories: (data) => {
      const { collections } = data
      const categoriesCollection = collections.categories
      const articleCategories = data.categories

      return categoriesCollection
        .filter((category) => articleCategories.includes(category.data.id))
    }
  }
}

Here I have created the computed property populatedCategories to get an array of categories all data related to the current article. I want to reuse this property in many places.

An example of such use - single article page and corresponding data file (https://github.com/monochromer/eleventy-deep-nested-computed-data/blob/main/src/entries/article/article.11tydata.js):

module.exports = {
  pagination: {
    data: 'collections.articles',
    size: 1,
    alias: 'article'
  },

  eleventyComputed: {
    permalink: (data) => {
      const { article } = data
      const { link } = article.data
      return link
    },

    // this doesn't work
    articleCategories: (data) => {
      const { article } = data
      const { populatedCategories } = article.data

      return populatedCategories
        .map?.((category) => ({
          id: category.data.id,
          title: category.data.title,
          link: category.data.link
        }))
    },

And template file:

<ul>
  {% for category in articleCategories %}
    <li>
      <a href="{{ category.link }}">
        {{ category.title }}
      </a>
    </li>
  {% endfor %}
</ul>

But instead of desired populatedCategories inside computed property articleCategories i get ''.

I found two workaround solutions:

  1. Return function instead of data (https://github.com/monochromer/eleventy-deep-nested-computed-data/blob/main/src/entries/article/article.11tydata.js#L45)
  2. Don't use nested computed property (https://github.com/monochromer/eleventy-deep-nested-computed-data/blob/main/src/entries/article/article.11tydata.js#L59). But this conflicts with my original idea of reuse.

To Reproduce Steps to reproduce the behavior:

  1. Go to repo
  2. Install deps npm ci
  3. Start dev server npm start
  4. Open some article, for example http://localhost:8080/articles/first/
  5. List after label "categories (desired)" shouldn't be empty

Expected behavior Computed property articleCategories return array of categories data.

Environment:

  • OS and Version: [Mac Catalina]
  • Eleventy Version [1.0.1]

monochromer avatar Jun 20 '22 09:06 monochromer