Querying JSON array in Nuxt 3 with Nuxt Content

1.5k Views Asked by At

How do I query a JSON array for a single element in Nuxt 3 and Nuxt Content?

├── @nuxt/[email protected]
└── [email protected]

content/people.json

[
  {
    "name": "Name1",
    "id": 1
  },
  {
    "name": "Name2",
    "id": 2
  }
]

Querying all of the people data results in this:

[
  {
    "_path": "/people",
    "_dir": "",
    "_draft": false,
    "_partial": false,
    "_locale": "en",
    "body": [
      {
        "name": "Name1",
        "id": 1
      },
      {
        "name": "Name2",
        "id": 2
      }
    ],
    "_id": "content:people.json",
    "_type": "json",
    "title": "People",
    "_source": "content",
    "_file": "people.json",
    "_extension": "json"
  }
]

pages/people/[id].vue

<template>
  <pre>{{ data }}</pre>
</template>

<script setup>
const route = useRoute();
const id = route.params.id;

const data = await queryContent("people")
  .where({ id }) // **What should this be? I can't seem to get any variants to work**
  .findOne();
</script>

I can query the full array of people okay on the index page. However, I would like to now get the single "person" out of the JSON array on the [id].vue page, but I'm not sure how to query this document with a where clause in Nuxt Content.

1

There are 1 best solutions below

0
On

In my opinion this question comes from a misunderstanding of the functionality of where() clause. This clause according to nuxt-content docs is used to Filter results by query. That means the results come from content directory of the nuxt app, Not the contents inside each file. It filters the files and folders, not the contents of them. For example when we say const { data } = await useAsyncData('list', () => queryContent('/list').where({ title: 'list1 page' }).findOne());, we want to filter the files inside the content/list directory and find the file that has title: 'list1 page'. We could not filter or change the contents inside the for example list1.md or list1.json or... files with where() clause.

For the case of this question, I think that we have two options:

  • The first one is that we filter the results in the people/[id].vue file after we get them from queryContent (without using where()) with the help of pure JavaScript (for example with filter() method) to get the person information according to id data.

  • The second option that I think is better, because allows us to benefit from nuxt-content features and functionalities is to change the data structure. To do that we must create a folder inside our content directory called people. Then inside that we create files like 1.person1.json, 2.person2.json and so on. Inside each file we have json data of that specific person like the code below:

    { "name": "Name1", "id": 1 }

    Then with a code like this one in pages/people/[id].vue file you can access the data of each person automatically according to the id of that person:

<template>
  <div>
    <p>{{ $route.params.id }}</p>
  </div>
</template>

<script setup>
const route = useRoute();
console.log(route.params.id);
const { data } = await useAsyncData('people', () => queryContent('people', "person"+ route.params.id).findOne());
console.log(data.value.name);
</script>

As you can see, in the second option we don't need to use where() clause at all, because the changing data structures makes the filtering process better and easier.