storyblok / field-plugin

Create and deploy Storyblok Field Plugin
https://www.storyblok.com/docs/plugins/field-plugins/introduction
25 stars 3 forks source link

Default options not working #390

Closed andyjamesn closed 1 month ago

andyjamesn commented 1 month ago

Describe the bug Created a Vue field plugin using monorepo with the cli

To Reproduce Steps to reproduce the behavior: Ass simple starter field to log the options

Add options to field-plugin.config.json

<script setup lang="ts">
import { useFieldPlugin } from '@storyblok/field-plugin/vue3';

const plugin = useFieldPlugin()

console.log(plugin);
</script>
{
  "options": [
    {
      "name": "option",
      "value": "value"
    }
  ]
}

Expected behavior Expect to log the options but it is emty

Screenshots CleanShot 2024-05-28 at 13 40 53@2x

Desktop (please complete the following information):

Additional context Using the sandbox I also see no default options are set

demetriusfeijoo commented 1 month ago

Hey @andyjamesn 👋 , thanks for reaching out to us and for all the provided details.

Since a field plugin is embedded within an iframe, all communication between the plugin and the container (such as the Sandbox) is done asynchronously. This means that if you try to access the data property right after calling the useFieldPlugin helper, it won't return anything.

The plugin needs to wait for the container to send the data back before it can use it. To determine when all the data is ready, you can check the plugin.type property to see if its value is loaded.

So, I would suggest you try the following approach which I think may fix the issue:

const plugin = useFieldPlugin()

watch(
  () => plugin.type,
  (type) => {
    if (type === 'loaded') { // make sure to access the data only after the plugin is correctly loaded.
      console.log('options', plugin.data?.options)
    }
  },
)

Let me know if it helped you 🙌

andyjamesn commented 1 month ago

Hey @demetriusfeijoo

I am already using the same watch in my code and had tested logging options in it.

I posted a simplified version of my code in my initial post.

I do this to create a setContent helper so I do not need to do plugin.actions.setContent and also to setup my initial content because even though I am adding it in validateContent it is not being set.

watch(
  () => plugin.type,
  (type) => {
    if (type === 'loaded') {
      setContent = plugin?.actions?.setContent
      Object.assign(form, plugin.data.content)
      // logging options is empty
      console.log(plugin?.data?.options)
    }
  },
)

Here is my entire file. I added your exact code too (but it is the same as mine) to be sure and get an empty object

<script setup>
import { reactive, watch } from 'vue'
import { useFieldPlugin } from '@storyblok/field-plugin/vue3'

const initialForm = {
  title: 'Hello',
  description: 'World',
}

const plugin = useFieldPlugin({
  validateContent: (content) => ({
    content:
      typeof content === 'object'
        ? content
        : {
            ...initialForm,
          },
  }),
})

// this is often undefined so we will set it in the watcher
let setContent = plugin?.actions?.setContent;

let form = reactive({ ...initialForm })

// watch plugin
watch(
  () => plugin.type,
  (type) => {
    if (type === 'loaded') {
      setContent = plugin?.actions?.setContent
      Object.assign(form, plugin.data.content)
      console.log(plugin?.data?.options)
    }
  },
)

// code from demetriusfeijoo <-- also empty options: {}
watch(
  () => plugin.type,
  (type) => {
    if (type === 'loaded') { // make sure to access the data only after the plugin is correctly loaded.
      console.log('options', plugin.data)
    }
  },
)

// watch form for changes and update content
watch(form, (v) => {
  setContent({ ...v })
});

</script>

<template>
  <SbTextField
    v-bind="{ label: 'Text input' }"
    v-model="form.title"
  />
  <SbTextField
    v-bind="{ label: 'Description' }"
    v-model="form.description"
  />

</template>
demetriusfeijoo commented 1 month ago

Thanks for the sample @andyjamesn, pretty helpful 💯

I tested it out here, and it worked nicely 🤔. I suspect the issue might be related to the options not being set correctly in the sandbox.

If so, could you confirm if the options you configured in the field-plugin.config.json are present in the sandbox URL, after running yarn dev?

Screenshot 2024-05-28 at 11 37 11

Screenshot 2024-05-28 at 11 29 49

andyjamesn commented 1 month ago

Ah I see. Since the options are set in the manifest, when options are added or changed the dev server needs to be restarted.

Thanks for all the help, all sorted now!