strapinuxt3.jsproxy-object

In Nuxt3, how to transform my proxy Object in a regular object?


Imagine I have a page 'PodcastPage', which is a component in Nuxt3 displaying a podcast page. This page simply gets the id in the URL in order to find the matching podcast to display, among all the podcasts I got from my database, which is a Strapi 4 backoffice.

    const { data: page } = await fetch(
       config.app.strapiBaseUri +
       `/api/podcast-pages?` +
       jsonToUrlParams({
          field: ["podcastPages", "Seo"],
          populate: {
            Seo: { populate: "*" },
          },
        }),
      {
        method: "GET",
        headers: { "Content-Type": "application/json" },
      }
    ).then((res) => res.json());
    console.log("page de podcast", page);

The console.log of 'page' show me a regular object. I try to hydrate a 'podcasts' variable to store all the podcasts from API answer.

const podcasts = ref([])
podcasts.value = page;

But when I do so, the console.log() of my 'podcasts' is a Proxy object:

   Proxy {0: {…}, 1: {…}, 2: {…}}
   [[Handler]]:Object
   [[Target]]:Array(3)
   0:
   attributes: 
   {breadcrumbTitle: 'page de podcast', title: 'blabla', date: '2022-09-15', content: '<p>bla.</p>', createdAt: '2023-03-05T15:31:28.566Z', …}
   id:1
   [[Prototype]]:Object

How to transform this Proxy item in a plain js object, because I then want to simply use 'find()' method in order to find the podcast matching with the id in the URL ? anyone can help me plz ?

This is all the methods I tried to hydrate my 'podcasts' array:

   podcasts.value = { ...page };
   podcasts.value = JSON.parse(JSON.stringify(page));
   podcasts.value = page.map((podcast) => {
     console.log(podcast)
     return Object.assign({}, podcast);
   });

When I console.log() podcasts this way

   console.log("podcasts", toRaw(podcasts.value));

The result is a regular object! but if I hydrate 'podcasts with

podcasts.value = toRaw(page);

It doesn't work either...

I can't use structuredClone because my node version is 16.19.3, and it commes with node v17

   podcasts.value = structuredClone(page);

All of those methods gives me the same result when I console.log() 'podcasts': the Proxy object we can see above.

I was reading this about structuredClone, and this article about Proxy object, but gave any result..

I am still a junior developper, and perhaps I 'overthink' the problem, or I miss something .. Can anyone help me for this one plz ?


Solution

  • To better understand what is going on here, you should read Vue.js Reactivity Fundamentals guide first. Nuxt is built atop Vue, so those essentials apply to it as well.

    ref() creates a special object that maintains reactive state in Vue applications and exposes its inner value through .value property. You cannot change it and you also shouldn't changed, because this is how Vue (and therefore also Nuxt, which is build atop it) help you with dynamic value changes.

    Inside your <template> sections refs will be automatically unwrapped, so there you can use {{ podcasts }} and get the actual value displayed, but inside <script> you need to access and manipulate data via podcasts.value.

    If you insist on unwrapping a ref manually in scripts, there is unref() function. But this will leave you with static data, that won't update after the page is loaded (which might or might not be what you need).

    Alternatively you can use reactive() to create a reactive object, that doesn't require you to access its contents with .value in scripts, but it has other limitations.