storyblok / storyblok-nuxt

Storyblok Nuxt module
https://www.storyblok.com/tp/nuxt-js-multilanguage-website-tutorial
MIT License
279 stars 44 forks source link

useAsyncStoryblok does not work with resolve_relations as expected #265

Closed awacode21 closed 7 months ago

awacode21 commented 1 year ago

According the docs on https://github.com/storyblok/storyblok-nuxt#2-getting-storyblok-stories-and-listen-to-visual-editor-events the composition api composable useAsyncStoryblok "is the short-hand equivalent to using useStoryblokApi inside useAsyncData and useStoryblokBridge functions separately" which i cannot confirm as i get different results.

When i use useAsyncStoryblok i get the direct story data:

Bildschirmfoto 2022-12-23 um 16 23 23

whereas when using useStoryblokApi i get an object which contains a story object but also other objects like rels and so on:

Bildschirmfoto 2022-12-23 um 16 25 45

So i get different data structures on both solutions. From a "short-hand equivalent" i would expect same behaviour.

Currently i need to load a story and resolve its relations. I did it as described here: https://www.storyblok.com/tp/create-and-render-blog-articles-in-storyblok-and-nuxt

but the result is only the story data, but not the rels object.

When i request it directly over browser url: https://api.storyblok.com/v2/cdn/stories/angebot/appartements?language=de&version=draft&token=246y8yrGbIXVFeVVWldUnQtt&resolve_relations=AppartementReference.appartements i get the result as expected. the overall object including story and relations.

When i request by using useStoryblokApi it is the same, i get the same results. Only when using useAsyncStoryblok i don't get the rels object, but regarding the documentation it should be there, as it is saying: "Resolved stories will be shown in a rels array at the end of the JSON response."

Expected Behavior

i would expect rels to be part of my useAsyncStoryblok response. i would expect useAsyncStoryblok and useStoryblokApi to deliver same data structure

Current Behavior

Even when following the documentation and official coding example i am not able to get the relations object over useAsyncStoryblok

Steps to Reproduce

1) open the stackblitz https://stackblitz.com/edit/nuxt-starter-aelmwe?file=package.json,nuxt.config.ts,app.vue 2) see reproduction in app.vue 3) have a look what is print out in dev tools console

SebbeJohansson commented 1 year ago

@awacode21 I would like to add that useStoryblok and useAsyncStoryblokboth return the same structure in the data.

I think the best way to solve this is to change so that useStoryblokApi returns the data the same way as useStoryblok rather than the other way around. This is because @Dawntraoz indicated to me that the suggested way to pull data is with useStoryblok when pulling in setup and useStoryblokApi only for when pulling outside of the setup fetch itself (like in a watch method).

awacode21 commented 7 months ago

@SebbeJohansson but with useStoryblok and useAsyncStoryblok i do not get the relations as i described. How to achieve to also receive the resolve_relations when using these composables? i need to workaround with useStoryblokApi to get my relations for 2 years now. Did you manage to do it differently?

in 2024 i still have this problem.

awacode21 commented 7 months ago

The interesting thing is, when i inspect the network tab... the response of the request is correct and contains the resolve relations, links & co. But the value the composable returns is just the story itself and you cannot access relations and links anymore.

So i think the problem is not the request itself, the problem is the value the composable returns

awacode21 commented 7 months ago

you can see it here at the end of the composable. ONLY the story gets returned. No chance to access the relations! From my perspective this is a Bug!

Bildschirmfoto 2024-04-19 um 22 01 39
SebbeJohansson commented 7 months ago

@awacode21 hi! Over a year later 😁

What version have you tried of the nuxt package? Could have sworn that it should work as expected now.

Maybe @Dawntraoz can confirm?

Dawntraoz commented 7 months ago

Hi folks 👋 Just to let you know, I'm no longer working on the Vue & Nuxt SDKs, but I leave you in good hands. Now @alvarosabu is in charge, and I can tell you he is the best for this! 🎉

In terms of the @awacode21 question, there's something that needs to be clarified, rels indeed is returned by the REST API response, but the js-client, the package that Vue SDK is on top of & this one too, is already merging the IDs mentioning these rels in the Story object itself, so there's no need of interacting with the rels property in the end project.

In the end, it was decided at some point to return only the needed content for the frontend project, but @alvarosabu can you double-check with @alexjoverm if there was a strong opinion on what to return from the composables? Can it be okay to return the rels too? But of course, now we need to take into account that will be a breaking change if we do so 🤔

awacode21 commented 7 months ago

The current version i am using is: "@storyblok/nuxt": "^6.0.10",

awacode21 commented 7 months ago

In my project this appartements list: https://www.bivignano.com/en/angebot/appartements and the "Other appartements" at the bottom of an appartements detail like https://www.bivignano.com/en/angebot/appartement/hexenhaeuschen are made by relations.

So this is really "needed" content. I don't understand what you mean by "is already merging the IDs mentioning these rels in the Story object itself, so there's no need of interacting with the rels property in the end project." do you have an example how this is meant? how can i access the rels from the story itself? Haven't seen anything on the story that helps. Or do i have to find the ids and do an extra api request for every single relation id to get the full data list? That would be worse, if that is the way to go it might be better to not use the composable and stay with storyblokApi.get to have it all in one request.

But from my perspective, ... if i have the option to ask for relations in the request and if the api request returns the relations they should also be accessible from the composable! In the documentation it is said that using the composable is the recommended way over using storyblokApi. But the composable is limited in functionality.

Dawntraoz commented 7 months ago

Hi @awacode21, indeed, it is needed content, and for that, it is already part of the story response thanks to the functionality of the js-client that is doing that, but of course, to get the relations content you need to provide the apiOptions with the resolve_relations: 'your_block.your_field'.

In short, the fields that are consider relations, initially are IDs, but the js-client is substituting those IDs by the actual response in the rels property. You can read more at the official js-client README https://github.com/storyblok/storyblok-js-client?tab=readme-ov-file#resolve-relations-using-the-storyblok-bridge. Is this clarifying your doubts?

If you are not getting these relations resolved in the story, then there's an API option missing for resolve_relations. Are you providing the same API options when using the other composables? 🤔

awacode21 commented 7 months ago

This is the request: https://api.storyblok.com/v2/cdn/stories/angebot/appartements?language=de&version=draft&token=246y8yrGbIXVFeVVWldUnQtt&resolve_relations=AppartementReference.appartements

i already provide the resolve_relations option. But in the response the relations info is part of rels outside of the story. the story itself does not contain info about the relations.

with storyblokApi i get the whole response and can select the story and the rels aswell. But the useAsyncStoryblok composable only returns the story. no access to relations. But the response of the request that was sent by the composable includes the relations.. the problem is only what the composable returns as object. only the story. That way no matter what i provided as api options i will have no access to it when using the useAsyncStoryblok composable. That is why i needed to stick with using storyblokApi directly. useAsyncStoryblok is unusable with my case.

awacode21 commented 7 months ago

So the request itself is not the problem. Also the api options are not the problem. That is working fine!

My problem is that the useAsyncStoryblok composable even if it receivces the relations from api it just strips it away as it only returns the story, but not story and relations. So actually it ignores that i requested also for the relations.

you can clearly see it here: https://github.com/storyblok/storyblok-nuxt/blob/main/src/runtime/composables/useAsyncStoryblok.ts

at the end it ignores what could have been under data.value?.data.rels ... because it only sets: story.value = data.value?.data.story and returns story.

ignoring any case of possible relations that where requested by api options and received by the api response.

Dawntraoz commented 7 months ago

That is the intended behavior when using the SDKs; even if you have access to the rels array in the storyblokApi response, we don't expect you to use it, but just use the story that has the merged relations.

Let me show you what is the expected behavior with the request you provided:

Once you use one of our SDK, built on top of the js-client, with your frontend project, you don't longer need to rely on the rels array anymore, the rels are now part of the story object for the first 2 levels of relations.

In your case, what was the reason to rely on the rels array in your project? Maybe we need to improve the docs if it wasn't clear enough that is not needed once you're using the js-client 🤔

SebbeJohansson commented 7 months ago

Hi! Yea it seems that @awacode21 is missunderstanding that the js-client automatically replaces the guids inside of the story object to contain the data from the rels. Everything should exist within the story that you need. Here is an example Before replacement by the client: image After: image

SebbeJohansson commented 7 months ago

@awacode21 If you really need the full result, you could pass it on as a prop. I do something similar here: https://github.com/SebbeJohansson/vrtx.ContentSystem/blob/75e6dec05b582c290fb7a66ec6950bd0807fa22b/pages/%5B...slug%5D.vue#L59 Keep in mind that I don't think this allows you access to the rels since this is one level extra up (I think).

alvarosabu commented 7 months ago

In the end, it was decided at some point to return only the needed content for the frontend project, but @alvarosabu can you double-check with @alexjoverm if there was a strong opinion on what to return from the composables? Can it be okay to return the rels too? But of course, now we need to take into account that will be a breaking change if we do so 🤔

Yes, this will entail a breaking change

awacode21 commented 7 months ago

Hi! Yea it seems that @awacode21 is missunderstanding that the js-client automatically replaces the guids inside of the story object to contain the data from the rels. Everything should exist within the story that you need. Here is an example Before replacement by the client: image After: image

Thank you so much for your explanation. You are right! I misunderstood. Actually i think i remember it was different in the past and there were only those ids which where not helpful. But it seems that changed meanwhile. Just checked my result with your example and it is fine.

So i will refactor my code to use the composable as everything i need is now part of the story. Thank you so much!

awacode21 commented 7 months ago

I close the issue as it seems it got fixed in the past. The ids for the relations in the story meanwhile get replaced with the actual relations data. So there is no longer a need to access the rels object outside of story.

SebbeJohansson commented 7 months ago

@awacode21 glad to hear it seems to be working! It seems logical that you started using it when it was somewhat broken.